Skip to content

Commit 0611899

Browse files
Merge branch 'coreui:main' into main
2 parents 9ad5d46 + 333919e commit 0611899

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1538
-1258
lines changed

packages/coreui-vue/src/components/form/CFormInput.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ const CFormInput = defineComponent({
188188
onInput: (event: InputEvent) => handleInput(event),
189189
readonly: props.readonly,
190190
type: props.type,
191-
...(props.modelValue && { value: props.modelValue }),
191+
...((props.modelValue || props.modelValue === 0) && { value: props.modelValue })
192192
},
193193
slots.default && slots.default(),
194194
),

packages/coreui-vue/src/components/table/CTable.ts

Lines changed: 243 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,51 @@
1-
import { defineComponent, h } from 'vue'
1+
import { computed, defineComponent, h, PropType } from 'vue'
22

33
import { Color } from '../props'
4+
import { CTableBody } from './CTableBody'
5+
import { CTableCaption } from './CTableCaption'
6+
import { CTableDataCell } from './CTableDataCell'
7+
import { CTableFoot } from './CTableFoot'
8+
import { CTableHead } from './CTableHead'
9+
import { CTableHeaderCell } from './CTableHeaderCell'
10+
import { CTableRow } from './CTableRow'
11+
12+
export interface Column {
13+
label?: string
14+
key: string
15+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16+
_style?: any
17+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
18+
_props?: any
19+
}
20+
21+
export interface FooterItem {
22+
label?: string
23+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
24+
_props?: any
25+
}
26+
27+
export type Item = {
28+
[key: string]: number | string | any
29+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
30+
_props?: any
31+
}
32+
33+
const pretifyName = (name: string) => {
34+
return name
35+
.replace(/[-_.]/g, ' ')
36+
.replace(/ +/g, ' ')
37+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
38+
.split(' ')
39+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
40+
.join(' ')
41+
}
42+
43+
const label = (column: Column | string) =>
44+
typeof column === 'object'
45+
? column.label !== undefined
46+
? column.label
47+
: pretifyName(column.key)
48+
: pretifyName(column)
449

550
const CTable = defineComponent({
651
name: 'CTable',
@@ -41,22 +86,61 @@ const CTable = defineComponent({
4186
/**
4287
* Put the `<caption>` on the top of the table.
4388
*
44-
* @values 'top'
89+
* @values 'top' | string
4590
*/
4691
caption: {
4792
type: String,
4893
default: undefined,
4994
required: false,
50-
validator: (value: string) => {
51-
return value === 'top'
52-
},
95+
},
96+
/**
97+
* Set the text of the table caption and the caption on the top of the table.
98+
*
99+
* @since 4.5.0
100+
*/
101+
captionTop: {
102+
type: String,
103+
default: undefined,
104+
required: false,
105+
},
106+
/**
107+
* Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '_props')
108+
*
109+
* In columns prop each array item represents one column. Item might be specified in two ways:
110+
* String: each item define column name equal to item value.
111+
* Object: item is object with following keys available as column configuration:
112+
* - key (required)(String) - define column name equal to item key.
113+
* - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word.
114+
* - _props (Object) - adds classes to all cels in column, ex. _props: { scope: 'col', className: 'custom-class' },
115+
* - _style (Object) - adds styles to the column header (useful for defining widths)
116+
*
117+
* @since 4.5.0
118+
*/
119+
columns: {
120+
type: Array as PropType<Column[] | string[]>,
121+
required: false,
53122
},
54123
/**
55124
* Sets the color context of the component to one of CoreUI’s themed colors.
56125
*
57126
* @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
58127
*/
59128
color: Color,
129+
/**
130+
* Array of objects or strings, where each element represents one cell in the table footer.
131+
*
132+
* Example items:
133+
* ['FooterCell', 'FooterCell', 'FooterCell']
134+
* or
135+
* [{ label: 'FooterCell', _props: { color: 'success' }, ...]
136+
*
137+
* @since 4.5.0
138+
*/
139+
footer: {
140+
type: Array as PropType<FooterItem[]>,
141+
default: () => [],
142+
required: false,
143+
},
60144
/**
61145
* Enable a hover state on table rows within a `<CTableBody>`.
62146
*/
@@ -65,10 +149,18 @@ const CTable = defineComponent({
65149
required: false,
66150
},
67151
/**
68-
* Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to.
152+
* Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.
69153
*
70-
* @values boolean, 'sm', 'md', 'lg', 'xl', 'xxl'
154+
* Example item:
155+
* { name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}
156+
*
157+
* @since 4.5.0
71158
*/
159+
items: {
160+
type: Array as PropType<Item[]>,
161+
default: () => [],
162+
required: false,
163+
},
72164
responsive: {
73165
type: [Boolean, String],
74166
default: undefined,
@@ -106,8 +198,39 @@ const CTable = defineComponent({
106198
type: Boolean,
107199
required: false,
108200
},
201+
/**
202+
* Properties that will be passed to the table footer component.
203+
*
204+
* Properties to [CTableFoot](#ctablefoot) component.
205+
* @since 4.5.0
206+
*/
207+
tableFootProps: {
208+
type: Object,
209+
default: undefined,
210+
required: false,
211+
},
212+
/**
213+
* Properties that will be passed to the table head component.
214+
*
215+
* Properties to [CTableHead](#ctablehead) component.
216+
* @since 4.5.0
217+
*/
218+
tableHeadProps: {
219+
type: Object,
220+
default: undefined,
221+
required: false,
222+
},
109223
},
110224
setup(props, { slots, attrs }) {
225+
const rawColumnNames = computed(() =>
226+
props.columns
227+
? props.columns.map((column: Column | string) => {
228+
if (typeof column === 'object') return column.key
229+
else return column
230+
})
231+
: Object.keys(props.items[0] || {}).filter((el) => el.charAt(0) !== '_'),
232+
)
233+
111234
const table = () =>
112235
h(
113236
'table',
@@ -116,7 +239,7 @@ const CTable = defineComponent({
116239
'table',
117240
{
118241
[`align-${props.align}`]: props.align,
119-
[`caption-${props.caption}`]: props.caption,
242+
[`caption-top`]: props.captionTop || props.caption === 'top',
120243
[`border-${props.borderColor}`]: props.borderColor,
121244
'table-bordered': props.bordered,
122245
'table-borderless': props.borderless,
@@ -129,7 +252,118 @@ const CTable = defineComponent({
129252
attrs.class,
130253
],
131254
},
132-
slots.default && slots.default(),
255+
{
256+
default: () => [
257+
((props.caption && props.caption !== 'top') || props.captionTop) &&
258+
h(
259+
CTableCaption,
260+
{},
261+
{
262+
default: () => props.caption || props.captionTop,
263+
},
264+
),
265+
props.columns &&
266+
h(
267+
CTableHead,
268+
{
269+
...props.tableHeadProps,
270+
},
271+
{
272+
default: () =>
273+
h(
274+
CTableRow,
275+
{},
276+
{
277+
default: () => [
278+
props.columns &&
279+
props.columns.map((column: Column | string) =>
280+
h(
281+
CTableHeaderCell,
282+
{
283+
...(typeof column === 'object' &&
284+
column._props && { ...column._props }),
285+
...(typeof column === 'object' &&
286+
column._style && { style: { ...column._style } }),
287+
},
288+
{
289+
default: () => label(column),
290+
},
291+
),
292+
),
293+
],
294+
},
295+
),
296+
},
297+
),
298+
props.items &&
299+
h(
300+
CTableBody,
301+
{},
302+
{
303+
default: () => [
304+
props.items.map((item: Item) =>
305+
h(
306+
CTableRow,
307+
{
308+
...(item._props && { ...item._props }),
309+
},
310+
{
311+
default: () => [
312+
rawColumnNames.value.map(
313+
(colName: string) =>
314+
item[colName] &&
315+
h(
316+
CTableDataCell,
317+
{
318+
...(item._cellProps &&
319+
item._cellProps['all'] && { ...item._cellProps['all'] }),
320+
...(item._cellProps &&
321+
item._cellProps[colName] && { ...item._cellProps[colName] }),
322+
},
323+
{
324+
default: () => item[colName],
325+
},
326+
),
327+
),
328+
],
329+
},
330+
),
331+
),
332+
],
333+
},
334+
),
335+
slots.default && slots.default(),
336+
props.footer &&
337+
h(
338+
CTableFoot,
339+
{
340+
...props.tableFootProps,
341+
},
342+
{
343+
default: () =>
344+
h(
345+
CTableRow,
346+
{},
347+
{
348+
default: () => [
349+
props.footer.map((item: FooterItem | string) =>
350+
h(
351+
CTableDataCell,
352+
{
353+
...(typeof item === 'object' && item._props && { ...item._props }),
354+
},
355+
{
356+
default: () => (typeof item === 'object' ? item.label : item),
357+
},
358+
),
359+
),
360+
],
361+
},
362+
),
363+
},
364+
),
365+
],
366+
},
133367
)
134368
return () => [
135369
props.responsive

packages/coreui-vue/src/components/table/CTableDataCell.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,18 @@ const CTableDataCell = defineComponent({
3131
* @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
3232
*/
3333
color: Color,
34+
/**
35+
* @ignore
36+
*/
37+
scope: {
38+
type: String,
39+
required: false,
40+
},
3441
},
3542
setup(props, { slots }) {
3643
return () =>
3744
h(
38-
'td',
45+
props.scope ? 'th' : 'td',
3946
{
4047
class: [
4148
{
@@ -44,6 +51,7 @@ const CTableDataCell = defineComponent({
4451
[`table-${props.color}`]: props.color,
4552
},
4653
],
54+
...(props.scope && { scope: props.scope }),
4755
},
4856
slots.default && slots.default(),
4957
)

packages/docs/.vuepress/clientAppEnhance.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
cibDiscourse,
1111
cibGithub,
1212
cibTwitter,
13+
cibOpenCollective,
1314
cilArrowBottom,
1415
cilArrowRight,
1516
cilArrowTop,
@@ -33,6 +34,7 @@ export const icons = {
3334
cibDiscourse,
3435
cibGithub,
3536
cibTwitter,
37+
cibOpenCollective,
3638
cilArrowBottom,
3739
cilArrowRight,
3840
cilArrowTop,

packages/docs/.vuepress/theme-coreui/src/client/components/Footer.vue

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,18 @@
2020
</ul>
2121
<p class="mb-0">CoreUI for Vue is Open Source UI Components Library for Vue.js.</p>
2222
<p class="mb-0">
23-
Currently v{{ version }}. Code licensed
23+
CoreUI code licensed
2424
<a
2525
href="https://github.com/coreui/coreui/blob/main/LICENSE"
2626
target="_blank"
2727
rel="license noopener"
28-
>
29-
MIT
30-
</a>
31-
, docs
28+
>MIT</a>, docs
3229
<a
3330
href="https://creativecommons.org/licenses/by/3.0/"
3431
target="_blank"
3532
rel="license noopener"
36-
>
37-
CC BY 3.0
38-
</a>
39-
.
33+
>CC BY 3.0</a>.
34+
<strong>CoreUI PRO requires a <a href="https://coreui.io/pricing/?framework=vue&docs=footer">commercial license</a>.</strong>
4035
</p>
4136
</CContainer>
4237
</CFooter>

0 commit comments

Comments
 (0)