@xleddyl/443-components-vue 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -27
- package/dist/components/forms/Calendar.vue +9 -4
- package/dist/components/forms/Calendar.vue.d.ts +1 -0
- package/dist/components/forms/CheckboxGroup.vue +2 -0
- package/dist/components/forms/CheckboxGroup.vue.d.ts +2 -1
- package/dist/components/forms/types.d.ts +1 -0
- package/dist/components/layout/Separator.vue +7 -1
- package/dist/components/layout/Separator.vue.d.ts +4 -1
- package/dist/components/layout/types.d.ts +1 -0
- package/dist/components/templates/DashboardLayout.vue +1 -1
- package/dist/composables/useForm.d.ts +2 -1
- package/dist/composables/useForm.mjs +13 -2
- package/dist/grid/cells/BadgeCell.vue +14 -3
- package/dist/grid/cells/BadgeCell.vue.d.ts +18 -4
- package/dist/grid/data-grid.css +3 -2
- package/dist/grid/types.d.ts +5 -1
- package/dist/styles/forced-colors.css +4 -0
- package/dist/styles/forms/calendar.css +13 -0
- package/dist/styles/forms/choice.css +7 -0
- package/dist/styles/layout/app-shell.css +43 -0
- package/dist/styles/layout/separator.css +11 -2
- package/dist/styles/overlays/command.css +1 -1
- package/dist/styles/templates/dashboard-layout.css +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,30 +100,48 @@ Vite 8 minifies CSS with Lightning CSS. Set `build.cssTarget` to browsers that s
|
|
|
100
100
|
|
|
101
101
|
## Theming
|
|
102
102
|
|
|
103
|
-
Tokens live on `.k-root`, never on `:root`. Override them on a root element:
|
|
103
|
+
Tokens live on `.k-root`, never on `:root`. Override them on a root element: host CSS, Root props or inline style.
|
|
104
|
+
|
|
105
|
+
The brand of an app is a custom theme: a class on the outermost root, with the token overrides in host CSS. Keep the brand values in this one place, not in Root props.
|
|
104
106
|
|
|
105
107
|
```vue
|
|
106
|
-
<KRoot
|
|
108
|
+
<KRoot class="theme-acme">...</KRoot>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```css
|
|
112
|
+
.k-root.theme-acme {
|
|
113
|
+
--k-accent: #ff4d00;
|
|
114
|
+
--k-accent-contrast: #ffffff;
|
|
115
|
+
--k-font-sans: 'Inter', sans-serif;
|
|
116
|
+
--k-radius-scale: 0.75;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Use Root props for values that change at runtime (an accent that the user selects, a preview, a demo):
|
|
121
|
+
|
|
122
|
+
```vue
|
|
123
|
+
<KRoot :accent="userAccent" theme="dark">
|
|
107
124
|
```
|
|
108
125
|
|
|
109
126
|
Input tokens, declared only on the outermost root so nested roots inherit them: `--k-accent`, `--k-accent-contrast`, `--k-font-sans`, `--k-font-mono`, `--k-font-size`, `--k-font-features`, `--k-line-height`, `--k-radius-scale`. Every other token (surfaces, text, lines, accent shades, status colors, radii, shadows, motion) is derived per root, so a nested root with its own `theme` or `accent` re-themes a region. The full list is in [CONVENTIONS.md](./CONVENTIONS.md#tokens).
|
|
110
127
|
|
|
111
128
|
A few component tokens are unset by default and only exist to be overridden on a root (or any ancestor). Unset, every one keeps the library look. The full list with defaults is in [CONVENTIONS.md](./CONVENTIONS.md#tokens):
|
|
112
129
|
|
|
113
|
-
| Area
|
|
114
|
-
|
|
|
115
|
-
| Type
|
|
116
|
-
| Buttons
|
|
117
|
-
| Fields
|
|
118
|
-
| Overlays
|
|
119
|
-
| Tooltip
|
|
120
|
-
| Shell
|
|
121
|
-
| Switch
|
|
122
|
-
| Separator
|
|
123
|
-
| Calendar
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
130
|
+
| Area | Tokens |
|
|
131
|
+
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
132
|
+
| Type | `--k-font-weight` (400), `--k-font-weight-medium` (500), `--k-font-weight-strong` (600), `--k-font-weight-display` (650) |
|
|
133
|
+
| Buttons | `--k-btn-highlight`, `--k-btn-shadow` (`0 0 #0000` for a flat button), `--k-btn-border`, `--k-btn-hover-background`, `--k-btn-active-background`, `--k-btn-padding-x`, `--k-btn-font-size`, `--k-btn-icon-size`, `--k-press-scale` (0.97) |
|
|
134
|
+
| Fields | `--k-field-padding-x` |
|
|
135
|
+
| Overlays | `--k-modal-radius`, `--k-modal-shadow`, `--k-drawer-radius`, `--k-drawer-shadow`, `--k-popover-radius`, `--k-popover-shadow`, `--k-toast-radius`, `--k-toast-shadow`, `--k-scrim-blur` (3px) |
|
|
136
|
+
| Tooltip | `--k-tooltip-background`, `--k-tooltip-text`, `--k-tooltip-border`, `--k-tooltip-radius`, `--k-tooltip-shadow`, `--k-tooltip-padding` |
|
|
137
|
+
| Shell | `--k-sidebar-width` (15rem), `--k-sidebar-rail-width`, `--k-topbar-height` (3rem), `--k-shell-inset`, `--k-shell-padding`, `--k-shell-content` |
|
|
138
|
+
| Switch | `--k-switch-track-width`, `--k-switch-track-height`, `--k-switch-thumb-size` (md size) |
|
|
139
|
+
| Separator | `--k-separator-heading-font-size` (0.9375rem), `--k-separator-heading-color` (`--k-text`), `--k-separator-label-font-size` (0.75rem) |
|
|
140
|
+
| Calendar | `--k-calendar-day-radius`, `--k-calendar-unavailable-color`, `--k-calendar-unavailable-decoration` (line-through), `--k-calendar-unavailable-opacity` (0.6), `--k-calendar-out-of-range-color`, `--k-calendar-out-of-range-decoration`, `--k-calendar-out-of-range-opacity` (each defaults to its unavailable token) |
|
|
141
|
+
| Checkbox group | `--k-checkbox-group-background`, `--k-checkbox-group-padding` (0.75rem), `--k-checkbox-group-radius`, `--k-checkbox-group-border` (`variant="filled"`) |
|
|
142
|
+
| Badge | `--k-badge-radius`, `--k-badge-font`, `--k-badge-font-size`, `--k-badge-font-weight`, `--k-badge-text-transform`, `--k-badge-letter-spacing` |
|
|
143
|
+
| DataGrid | `--k-grid-header-background`, `--k-grid-header-text`, `--k-grid-header-font`, `--k-grid-header-font-weight`, `--k-grid-header-font-size` (12px), `--k-grid-font-size` (13px), `--k-grid-radius`, `--k-grid-selected-background` |
|
|
144
|
+
| Charts | `--k-chart-1` to `--k-chart-8` (series palette) |
|
|
127
145
|
|
|
128
146
|
Some tokens are meant for one element: set `--k-btn-tone`, `--k-btn-on-tone` and `--k-btn-tone-text` on a button for a brand tone outside `Tone` (a lime fill with green text), and `--k-badge-background`, `--k-badge-color` and `--k-badge-border-color` on a badge for a custom pill color. `variant="subtle"` is a borderless tinted fill (`--k-fill` for the neutral tone). For solid buttons without hover darkening, declare the fill tokens on the button so `var(--k-btn-tone)` resolves per tone: `.k-btn-solid { --k-btn-hover-background: var(--k-btn-tone); --k-btn-active-background: var(--k-btn-tone) }` (the neutral solid button rests on `--k-text`).
|
|
129
147
|
|
|
@@ -168,14 +186,10 @@ import '@fontsource-variable/funnel-display'
|
|
|
168
186
|
import '@fontsource-variable/geist-mono'
|
|
169
187
|
```
|
|
170
188
|
|
|
171
|
-
Presets set the input tokens (accent, accent contrast and accent text, fonts, font features, radius scale) and the surface, line and text tokens.
|
|
172
|
-
|
|
173
|
-
```vue
|
|
174
|
-
<KRoot accent="#ff4d00" accent-contrast="#ffffff" :radius-scale="0.5" theme="dark">...</KRoot>
|
|
175
|
-
```
|
|
189
|
+
Presets set the input tokens (accent, accent contrast and accent text, fonts, font features, radius scale) and the surface, line and text tokens. Unlayered host CSS, Root props and inline style still win, so a custom theme on top of a preset is a few lines of host CSS (see [Theming](#theming)):
|
|
176
190
|
|
|
177
191
|
```css
|
|
178
|
-
.k-root.
|
|
192
|
+
.k-root.theme-acme {
|
|
179
193
|
--k-accent: #ff4d00;
|
|
180
194
|
--k-radius-scale: 0.5;
|
|
181
195
|
}
|
|
@@ -183,6 +197,8 @@ Presets set the input tokens (accent, accent contrast and accent text, fonts, fo
|
|
|
183
197
|
|
|
184
198
|
Semantic color props are always called `tone` and accept `'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'` (type `Tone`).
|
|
185
199
|
|
|
200
|
+
Buttons show `icon` before the label and `trailingIcon` after it. Put action icons (`plus`, `trash`, `pencil`) in `icon`. Put direction icons (`arrow-right`, `chevron-right`, `arrow-top-right-on-square`) in `trailingIcon`: `<KButton trailing-icon="arrow-right">Continue</KButton>`.
|
|
201
|
+
|
|
186
202
|
## Scoping
|
|
187
203
|
|
|
188
204
|
- The reset only matches `.k-root` and its descendants, wrapped in `:where()` (zero specificity). Markup outside a root keeps browser defaults.
|
|
@@ -251,6 +267,8 @@ Built-in messages follow the active language. `messages` overrides them for one
|
|
|
251
267
|
|
|
252
268
|
`schema` also accepts a ref or getter (`MaybeRefOrGetter<FormSchema>`), for one form component reused with different fields, labels or rules per open, mode or language: `schema: () => (mode.value === 'edit' ? editSchema : createSchema)`. Field definitions, labels, `required` and rules follow the source (after the first submit the form validates again when they change). A field that appears starts from its `initial` and is clean; a field that disappears loses its value, error and touched state. With `values` the host owns the values, so only rules and labels change. `form.schema` always returns the current definitions.
|
|
253
269
|
|
|
270
|
+
`required` is a boolean or a function of the current values (`FieldRequired`, `boolean | ((values) => boolean)`) for conditional fields: `required: (values) => values.delivery === 'ship'`. The `FormField` required marker, `aria-required` and `form.isRequired(name)` follow the current result, and after the first submit the form validates again when it changes.
|
|
271
|
+
|
|
254
272
|
`required` treats `null`, `undefined`, blank strings, empty arrays, `NaN` and plain objects whose values are all empty (a per-language map like `{ it: '', en: '' }`) as empty. A field with another idea of empty passes `isEmpty: (value) => boolean`, which replaces the check for that field. `isEmptyValue(value)` is the default check, exported for reuse.
|
|
255
273
|
|
|
256
274
|
A `validate` function returns a message, `false` (the built-in invalid message), nothing (valid), or `{ message, params }` when the message needs values: `validate: (value) => value.length > 80 ? { message: 'errors.maxLength', params: { max: 80 } } : undefined`. The params reach `translateMessage` as `context.params`; without a translator they fill the `{name}` placeholders of the message.
|
|
@@ -325,12 +343,12 @@ Composables: `useTheme`, `usePreset`, `useForm`, `useField`, `useFieldControl`,
|
|
|
325
343
|
- `Input` and `Textarea` take `counter`: with a `maxlength` attribute they show `length / maxlength` inside the field, describe the control with "12 of 40 characters" (`form.characterCount`) and announce "Character limit reached" when it is hit.
|
|
326
344
|
- `Input` takes `transform: (value: string) => string`, applied to the typed text before it reaches the model (the caret keeps its place; IME composition is transformed when it ends). `:transform="(value) => value.toUpperCase()"` enforces uppercase codes. Values set from outside are not transformed.
|
|
327
345
|
- `FormField` takes `optional`, a muted localized "Optional" marker in the label row (`form.optional`, `optionalText` overrides it), the counterpart of the required asterisk. It is hidden when the field is required.
|
|
328
|
-
- `CheckboxGroup` takes `columns` (a number): the options are laid out in a grid with that many equal columns. Unset keeps the `orientation` layout.
|
|
346
|
+
- `CheckboxGroup` takes `columns` (a number): the options are laid out in a grid with that many equal columns. Unset keeps the `orientation` layout. `variant="filled"` (`CheckboxGroupVariant`, `'default' | 'filled'`, default `'default'`) puts the options in a subtle filled panel, styled by `--k-checkbox-group-background` (`--k-subtle`), `--k-checkbox-group-padding` (0.75rem), `--k-checkbox-group-radius` (`--k-radius-md`) and `--k-checkbox-group-border` (none).
|
|
329
347
|
- `Combobox` with `multiple` takes `hideTags`: the selected values are not rendered as tags inside the control (the host shows them elsewhere), the placeholder stays visible and Backspace no longer removes the last value. Selection is still announced through the options.
|
|
330
348
|
- `Pagination` takes `showEdges` (first and last page buttons, `firstLabel`, `lastLabel`) and `showJump` (a typed page number, `jumpLabel`). Both are off by default. `page` is clamped to the page count only when `total` is known: while `total` is `0` or `loading` is set (it also sets `aria-busy`), the page is kept, so a server reload does not reset it.
|
|
331
349
|
- `FilterPills` can list active filters: options with `removable: true` render as active pills with a remove button (`removeLabel`, a `'Remove {label}'` template). Clicking the pill emits `select(value)`, the button emits `remove(value)` (and drops the value from the model when it is selected); focus moves to the next pill when the removed one disappears.
|
|
332
|
-
- `Calendar` takes `dayText: (iso) => string | undefined`, a short line under each day number that is also added to the day's accessible name (availability, prices). The `#day` slot (`{ date, number, text, selected, unavailable, inMonth }`) replaces the cell content; it is decorative, so announced text still comes from `dayText`.
|
|
333
|
-
- `Separator` takes `description` (or `#description`) under its label, and an `#actions` slot rendered next to them (a small add or edit button). `variant="heading"` (`SeparatorVariant`, `'label' | 'heading'`, default `'label'`) shows the label as a section title on its own (an `h3`, `level` changes it) with the description below and the actions at the end, under one line above instead of the small muted label between two lines. `:lines="false"` (default `true`) hides the lines of either variant
|
|
350
|
+
- `Calendar` takes `dayText: (iso) => string | undefined`, a short line under each day number that is also added to the day's accessible name (availability, prices). The `#day` slot (`{ date, number, text, selected, unavailable, outOfRange, inMonth }`) replaces the cell content; it is decorative, so announced text still comes from `dayText`. Days before `min` or after `max` get the `is-out-of-range` class (and `is-unavailable`, like days rejected by `isDateDisabled`), so the `--k-calendar-out-of-range-*` tokens style them apart from disabled days.
|
|
351
|
+
- `Separator` takes `description` (or `#description`) under its label, and an `#actions` slot rendered next to them (a small add or edit button). `variant="heading"` (`SeparatorVariant`, `'label' | 'heading'`, default `'label'`) shows the label as a section title on its own (an `h3`, `level` changes it) with the description below and the actions at the end, under one line above instead of the small muted label between two lines. `:lines="false"` (default `true`) hides the lines of either variant. `align` (`SeparatorAlign`, `'start' | 'center'`, default `'start'`) centers the heading title and description. `--k-separator-heading-font-size` (0.9375rem) sizes the heading, `--k-separator-heading-color` (default `--k-text`) colors it, and `--k-separator-label-font-size` (0.75rem) sizes the small label of `variant="label"`, with or without lines.
|
|
334
352
|
- `Modal` takes `width` (any CSS length, overrides `size`) and `minHeight` (keeps the height steady while tabs or steps change). The size widths are tokens: `--k-modal-width-sm` (26rem), `--k-modal-width-md` (32rem), `--k-modal-width-lg` (50rem), `--k-modal-width-xl` (64rem).
|
|
335
353
|
- `Tabs` items take `dot: true` for a small indicator without a number (`dotTone`, default `danger`; `dotLabel` is the hidden text, default "Needs attention").
|
|
336
354
|
- `DropdownMenu` takes `matchTriggerWidth` (the menu is at least as wide as its trigger) and `minWidth` (a CSS length).
|
|
@@ -449,7 +467,7 @@ Ready defaults to start a dashboard project: an app frame, an auth frame and pag
|
|
|
449
467
|
| `breadcrumbs` | | Rendered in the desktop topbar. `#topbar` replaces them, `#actions` adds buttons on the right. |
|
|
450
468
|
| `search` | `false` | `true` adds a CommandPalette with every navigation item, an array adds your own command groups, an async function `(query, signal) => CommandGroup<T>[]` searches on your server (item `data` reaches `#search-item` typed) (matching navigation items come first unless `searchNavigation` is `false`). `#search` replaces it. |
|
|
451
469
|
| `searchProps` | | Options for the built-in CommandPalette: `minQueryLength`, `debounce`, `placeholder`, `label`, `emptyText` (a string or `(query) => string`), `minQueryText`, `errorText`, `loadingText`, `resultsText`, `notice`, `recentKey`, footer labels. Slots `#search-item`, `#search-empty`, `#search-group-label` and `#search-after-results` reach the palette. |
|
|
452
|
-
| `themeSwitch` | `
|
|
470
|
+
| `themeSwitch` | `false` | `'sidebar'`, `'topbar'` or `false`. The default keeps the theme choice only in the Appearance section of the settings modal. With `accountAction="menu"` there is no settings modal, so set `'sidebar'` or `'topbar'`. |
|
|
453
471
|
| `collapsible`, `v-model:collapsed`, `storageKey` | `true`, `'k-sidebar-collapsed'` | Icon rail on desktop. Persisted in a cookie under Nuxt (rendered on the server, no flash) or `localStorage` elsewhere. `false` disables persistence. |
|
|
454
472
|
| `shortcut` | `'mod+b'` | Toggles the rail on desktop and the drawer on mobile. `searchShortcut` defaults to `mod+k`. |
|
|
455
473
|
| `v-model:open` | `false` | Mobile drawer (below 768px of shell width): scrim, focus moves into the drawer, the content is `inert`, Escape and the scrim close it and focus returns to the burger. |
|
|
@@ -586,7 +604,7 @@ export default defineAppConfig({
|
|
|
586
604
|
],
|
|
587
605
|
signOutTo: '/logout',
|
|
588
606
|
},
|
|
589
|
-
dashboard: { variant: 'inset', search: true
|
|
607
|
+
dashboard: { variant: 'inset', search: true },
|
|
590
608
|
auth: { variant: 'split', footer: 'Acme Inc.', asideTitle: 'Run the store.' },
|
|
591
609
|
},
|
|
592
610
|
})
|
|
@@ -646,6 +664,7 @@ Accessibility related props and defaults:
|
|
|
646
664
|
- `DataGrid` `showEdges` and `showJump` reach the footer pager (first and last page buttons, page number input). `loading` also keeps the pager from resetting the page while a server total is unknown.
|
|
647
665
|
- `DataGrid` registers the AG Grid cell editors (text, large text, number, date, checkbox, select, custom and undo/redo) when `editable` is set or when a column or `gridOptions.defaultColDef` has `editable` at mount. `registerGridEditorModules()` from `/grid` does it by hand, before the first grid mounts, for columns that become editable later.
|
|
648
666
|
- `ImageCell` takes `fit` (`'cover'` default, or `'contain'` for logos) and `size` (any CSS length, default `1.75rem`) in `cellRendererParams`. `EmptyCell` (the hidden "Empty" dash) is exported from `/grid` for custom renderers.
|
|
667
|
+
- `BadgeCell` takes `variant` (`BadgeVariant`, `'soft' | 'solid' | 'outline'`) in `cellRendererParams`: set, the cell renders a `KBadge` with that variant and the resolved tone (`size`, `BadgeSize`, default `'sm'`); unset keeps the compact grid pill. `badgeClass` (`string | ((value, data) => string | undefined)`) adds host classes to the badge, to set the per instance badge tokens (`--k-badge-background`, `--k-badge-color`, `--k-badge-border-color`, which the grid pill also reads) for values outside `Tone`. `BadgeCellParams<T>` types the row of `data`.
|
|
649
668
|
- `DataGrid` translates the AG Grid ARIA strings through the catalog (`grid.*`; your own `localeText` still wins) and announces row count changes.
|
|
650
669
|
|
|
651
670
|
## Browser support
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
'is-today': day.iso === today,
|
|
67
67
|
'is-selected': day.selected,
|
|
68
68
|
'is-unavailable': day.unavailable,
|
|
69
|
+
'is-out-of-range': day.outOfRange,
|
|
69
70
|
'is-range-start': day.rangeStart,
|
|
70
71
|
'is-range-end': day.rangeEnd,
|
|
71
72
|
'is-in-range': day.inRange,
|
|
@@ -90,6 +91,7 @@
|
|
|
90
91
|
:text="day.text"
|
|
91
92
|
:selected="day.selected"
|
|
92
93
|
:unavailable="day.unavailable"
|
|
94
|
+
:out-of-range="day.outOfRange"
|
|
93
95
|
:in-month="day.inMonth"
|
|
94
96
|
>
|
|
95
97
|
{{ day.number }}
|
|
@@ -185,10 +187,11 @@ const previewEnd = computed(() => {
|
|
|
185
187
|
if (!props.range || !start || end) return null;
|
|
186
188
|
return hoverDate.value ?? null;
|
|
187
189
|
});
|
|
190
|
+
function isOutOfRange(iso) {
|
|
191
|
+
return Boolean(props.min && iso < props.min || props.max && iso > props.max);
|
|
192
|
+
}
|
|
188
193
|
function isUnavailable(iso) {
|
|
189
|
-
|
|
190
|
-
if (props.max && iso > props.max) return true;
|
|
191
|
-
return Boolean(props.isDateDisabled?.(iso));
|
|
194
|
+
return isOutOfRange(iso) || Boolean(props.isDateDisabled?.(iso));
|
|
192
195
|
}
|
|
193
196
|
function dayLabel(iso, start, end) {
|
|
194
197
|
const label = formatIso(iso, resolvedLocale.value, {
|
|
@@ -211,6 +214,7 @@ const weeks = computed(() => {
|
|
|
211
214
|
const [previewFrom, previewTo] = start && preview ? preview < start ? [preview, start] : [start, preview] : [null, null];
|
|
212
215
|
const days = monthGrid(firstOfMonth(focusedDate.value), weekStart.value).map((iso) => {
|
|
213
216
|
const inMonth = monthKey(iso) === currentMonth;
|
|
217
|
+
const outOfRange = isOutOfRange(iso);
|
|
214
218
|
const selected = Boolean(
|
|
215
219
|
start && (props.range ? iso === start || iso === end : iso === start)
|
|
216
220
|
);
|
|
@@ -220,7 +224,8 @@ const weeks = computed(() => {
|
|
|
220
224
|
number: Number(iso.slice(8)),
|
|
221
225
|
text: props.dayText?.(iso),
|
|
222
226
|
label: dayLabel(iso, start, end),
|
|
223
|
-
|
|
227
|
+
outOfRange,
|
|
228
|
+
unavailable: outOfRange || Boolean(props.isDateDisabled?.(iso)),
|
|
224
229
|
selected: selected || Boolean(props.range && start && end && iso > start && iso < end),
|
|
225
230
|
rangeStart: Boolean(props.range && start && end && iso === start && start !== end),
|
|
226
231
|
rangeEnd: Boolean(props.range && start && end && iso === end && start !== end),
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
class="k-choice-group k-checkbox-group"
|
|
10
10
|
:class="[
|
|
11
11
|
`k-choice-group-${orientation}`,
|
|
12
|
+
`k-checkbox-group-${variant}`,
|
|
12
13
|
{
|
|
13
14
|
'is-invalid': control.invalid.value,
|
|
14
15
|
'is-disabled': control.disabled.value,
|
|
@@ -48,6 +49,7 @@ const props = defineProps({
|
|
|
48
49
|
label: { type: String, required: false },
|
|
49
50
|
legend: { type: String, required: false },
|
|
50
51
|
orientation: { type: String, required: false, default: "vertical" },
|
|
52
|
+
variant: { type: String, required: false, default: "default" },
|
|
51
53
|
columns: { type: Number, required: false },
|
|
52
54
|
size: { type: String, required: false, default: "md" },
|
|
53
55
|
name: { type: String, required: false },
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { FieldSize } from '../core/types';
|
|
2
|
-
import type { ChoiceOption, ChoiceOrientation, ChoiceValue } from './types';
|
|
2
|
+
import type { CheckboxGroupVariant, ChoiceOption, ChoiceOrientation, ChoiceValue } from './types';
|
|
3
3
|
declare const __VLS_export: <T extends ChoiceValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
4
4
|
props: import("vue").PublicProps & __VLS_PrettifyLocal<({
|
|
5
5
|
options?: ChoiceOption<T>[];
|
|
6
6
|
label?: string;
|
|
7
7
|
legend?: string;
|
|
8
8
|
orientation?: ChoiceOrientation;
|
|
9
|
+
variant?: CheckboxGroupVariant;
|
|
9
10
|
columns?: number;
|
|
10
11
|
size?: FieldSize;
|
|
11
12
|
name?: string;
|
|
@@ -58,6 +58,7 @@ export type FileInputDirectory = boolean | 'drop';
|
|
|
58
58
|
export type FileInputAcceptMode = 'filter' | 'hint';
|
|
59
59
|
export type PinInputMode = 'numeric' | 'alphanumeric' | 'alphabetic';
|
|
60
60
|
export type RadioGroupVariant = 'default' | 'card';
|
|
61
|
+
export type CheckboxGroupVariant = 'default' | 'filled';
|
|
61
62
|
export type SliderBubble = boolean | 'always';
|
|
62
63
|
export type ColorSwatch = string | {
|
|
63
64
|
value: string;
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
class="k-separator"
|
|
4
4
|
:class="[
|
|
5
5
|
`k-separator-${orientation}`,
|
|
6
|
-
{
|
|
6
|
+
{
|
|
7
|
+
'k-separator-heading': isHeading,
|
|
8
|
+
'k-separator-center': isHeading && align === 'center',
|
|
9
|
+
'has-label': hasContent,
|
|
10
|
+
'no-lines': !lines
|
|
11
|
+
}
|
|
7
12
|
]"
|
|
8
13
|
:role="plain ? 'none' : 'separator'"
|
|
9
14
|
:aria-orientation="!plain && orientation === 'vertical' ? 'vertical' : void 0"
|
|
@@ -36,6 +41,7 @@ const props = defineProps({
|
|
|
36
41
|
orientation: { type: String, required: false, default: "horizontal" },
|
|
37
42
|
variant: { type: String, required: false, default: "label" },
|
|
38
43
|
lines: { type: Boolean, required: false, default: true },
|
|
44
|
+
align: { type: String, required: false, default: "start" },
|
|
39
45
|
level: { type: Number, required: false, default: 3 },
|
|
40
46
|
label: { type: String, required: false },
|
|
41
47
|
description: { type: String, required: false },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HeadingLevel, SeparatorVariant } from './types';
|
|
1
|
+
import type { HeadingLevel, SeparatorAlign, SeparatorVariant } from './types';
|
|
2
2
|
declare var __VLS_13: {}, __VLS_21: {}, __VLS_23: {};
|
|
3
3
|
type __VLS_Slots = {} & {
|
|
4
4
|
default?: (props: typeof __VLS_13) => any;
|
|
@@ -11,6 +11,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
11
11
|
orientation?: "horizontal" | "vertical";
|
|
12
12
|
variant?: SeparatorVariant;
|
|
13
13
|
lines?: boolean;
|
|
14
|
+
align?: SeparatorAlign;
|
|
14
15
|
level?: HeadingLevel;
|
|
15
16
|
label?: string;
|
|
16
17
|
description?: string;
|
|
@@ -211,6 +212,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
211
212
|
orientation?: "horizontal" | "vertical";
|
|
212
213
|
variant?: SeparatorVariant;
|
|
213
214
|
lines?: boolean;
|
|
215
|
+
align?: SeparatorAlign;
|
|
214
216
|
level?: HeadingLevel;
|
|
215
217
|
label?: string;
|
|
216
218
|
description?: string;
|
|
@@ -410,6 +412,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
410
412
|
}> & Readonly<{}>, {
|
|
411
413
|
orientation: "horizontal" | "vertical";
|
|
412
414
|
variant: SeparatorVariant;
|
|
415
|
+
align: SeparatorAlign;
|
|
413
416
|
level: HeadingLevel;
|
|
414
417
|
lines: boolean;
|
|
415
418
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -46,6 +46,7 @@ export type AccordionVariant = 'separated' | 'plain' | 'card' | 'outline';
|
|
|
46
46
|
export type AccordionContentVariant = 'text' | 'neutral';
|
|
47
47
|
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
48
48
|
export type SeparatorVariant = 'label' | 'heading';
|
|
49
|
+
export type SeparatorAlign = 'start' | 'center';
|
|
49
50
|
export interface AppShellContext {
|
|
50
51
|
sidebarId: string;
|
|
51
52
|
collapsed: Readonly<{
|
|
@@ -189,7 +189,7 @@ const props = defineProps({
|
|
|
189
189
|
searchPlaceholder: { type: String, required: false },
|
|
190
190
|
searchShortcut: { type: [String, Boolean], required: false, default: "mod+k" },
|
|
191
191
|
searchNavigationLabel: { type: String, required: false },
|
|
192
|
-
themeSwitch: { type: [String, Boolean], required: false, default:
|
|
192
|
+
themeSwitch: { type: [String, Boolean], required: false, default: false },
|
|
193
193
|
collapsible: { type: Boolean, required: false, default: true },
|
|
194
194
|
storageKey: { type: [String, Boolean], required: false, default: "k-sidebar-collapsed" },
|
|
195
195
|
shortcut: { type: [String, Boolean], required: false, default: "mod+b" },
|
|
@@ -7,10 +7,11 @@ export interface FieldValidationMessage {
|
|
|
7
7
|
params?: MessageParams;
|
|
8
8
|
}
|
|
9
9
|
export type FieldValidationResult = string | FieldValidationMessage | undefined | null | boolean;
|
|
10
|
+
export type FieldRequired = boolean | ((values: Record<string, unknown>) => boolean);
|
|
10
11
|
export interface FieldDefinition<T = unknown> {
|
|
11
12
|
initial?: T | (() => T);
|
|
12
13
|
label?: string;
|
|
13
|
-
required?:
|
|
14
|
+
required?: FieldRequired;
|
|
14
15
|
min?: number;
|
|
15
16
|
max?: number;
|
|
16
17
|
minLength?: number;
|
|
@@ -185,6 +185,10 @@ export function useForm(options) {
|
|
|
185
185
|
async function runValidator() {
|
|
186
186
|
return evaluateValidator();
|
|
187
187
|
}
|
|
188
|
+
function isFieldRequired(name) {
|
|
189
|
+
const required = schema.value[name]?.required;
|
|
190
|
+
return typeof required === "function" ? Boolean(required(target())) : Boolean(required);
|
|
191
|
+
}
|
|
188
192
|
function evaluateRules(name) {
|
|
189
193
|
const definition = schema.value[name];
|
|
190
194
|
if (!definition) return void 0;
|
|
@@ -205,7 +209,7 @@ export function useForm(options) {
|
|
|
205
209
|
maxLength: definition.maxLength
|
|
206
210
|
};
|
|
207
211
|
if (definition.isEmpty ? definition.isEmpty(value) : isEmptyValue(value)) {
|
|
208
|
-
if (
|
|
212
|
+
if (isFieldRequired(name)) return fieldMessages.required(context);
|
|
209
213
|
} else {
|
|
210
214
|
if (typeof value === "number") {
|
|
211
215
|
if (definition.min !== void 0 && value < definition.min)
|
|
@@ -436,6 +440,13 @@ export function useForm(options) {
|
|
|
436
440
|
},
|
|
437
441
|
{ deep: 2 }
|
|
438
442
|
);
|
|
443
|
+
watch(
|
|
444
|
+
() => names.value.map((name) => isFieldRequired(name)),
|
|
445
|
+
(next, previous) => {
|
|
446
|
+
if (submitCount.value > 0 && next.some((required, index) => required !== previous[index]))
|
|
447
|
+
void validate();
|
|
448
|
+
}
|
|
449
|
+
);
|
|
439
450
|
watch(
|
|
440
451
|
() => toValue(options.validator),
|
|
441
452
|
() => {
|
|
@@ -491,7 +502,7 @@ export function useForm(options) {
|
|
|
491
502
|
setErrors,
|
|
492
503
|
clearErrors,
|
|
493
504
|
touch,
|
|
494
|
-
isRequired:
|
|
505
|
+
isRequired: isFieldRequired,
|
|
495
506
|
reset,
|
|
496
507
|
submit
|
|
497
508
|
};
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<template v-if="text">
|
|
3
|
+
<Badge v-if="params.variant" :class="badgeClass" :tone :variant="params.variant" :size>{{
|
|
4
|
+
text
|
|
5
|
+
}}</Badge>
|
|
6
|
+
<span v-else class="k-data-grid-badge" :class="[`k-data-grid-badge-${tone}`, badgeClass]">{{
|
|
7
|
+
text
|
|
8
|
+
}}</span>
|
|
9
|
+
</template>
|
|
5
10
|
<EmptyCell v-else :context="cellContext" />
|
|
6
11
|
</template>
|
|
7
12
|
|
|
8
13
|
<script setup>
|
|
9
14
|
import { computed } from "vue";
|
|
15
|
+
import Badge from "../../components/data/Badge.vue";
|
|
10
16
|
import EmptyCell from "./EmptyCell.vue";
|
|
11
17
|
const props = defineProps({
|
|
12
18
|
params: { type: Object, required: true }
|
|
@@ -19,5 +25,10 @@ const text = computed(() => key.value ? props.params.labels?.[key.value] ?? key.
|
|
|
19
25
|
const tone = computed(
|
|
20
26
|
() => props.params.tones?.[key.value] ?? props.params.defaultTone ?? "neutral"
|
|
21
27
|
);
|
|
28
|
+
const size = computed(() => props.params.size ?? "sm");
|
|
29
|
+
const badgeClass = computed(() => {
|
|
30
|
+
const source = props.params.badgeClass;
|
|
31
|
+
return typeof source === "function" ? source(props.params.value, props.params.data) : source;
|
|
32
|
+
});
|
|
22
33
|
const cellContext = computed(() => props.params.context);
|
|
23
34
|
</script>
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { BadgeCellParams, GridCellContext } from '../types';
|
|
2
2
|
declare const __VLS_export: import("vue").DefineComponent<{
|
|
3
|
-
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams
|
|
3
|
+
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams<unknown>;
|
|
4
|
+
label?: string | number;
|
|
5
|
+
tone?: import("../../index.ts").Tone;
|
|
6
|
+
variant?: import("../../index.ts").BadgeVariant;
|
|
7
|
+
size?: import("../../index.ts").BadgeSize;
|
|
8
|
+
dot?: boolean;
|
|
9
|
+
pulse?: boolean;
|
|
10
|
+
icon?: import("../../index.ts").IconName;
|
|
4
11
|
innerHTML?: string | undefined | undefined;
|
|
5
12
|
class?: import("vue").ClassValue;
|
|
6
13
|
style?: import("vue").StyleValue;
|
|
@@ -193,15 +200,22 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
193
200
|
ref?: import("vue").VNodeRef | undefined;
|
|
194
201
|
ref_for?: boolean | undefined | undefined;
|
|
195
202
|
ref_key?: string | undefined | undefined;
|
|
196
|
-
context?: GridCellContext;
|
|
197
203
|
onVnodeBeforeMount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
198
204
|
onVnodeMounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
199
205
|
onVnodeBeforeUpdate?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
200
206
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
201
207
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
202
208
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
209
|
+
context?: GridCellContext;
|
|
203
210
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
204
|
-
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams
|
|
211
|
+
params: import("ag-grid-community").ICellRendererParams<any, any, any> & BadgeCellParams<unknown>;
|
|
212
|
+
label?: string | number;
|
|
213
|
+
tone?: import("../../index.ts").Tone;
|
|
214
|
+
variant?: import("../../index.ts").BadgeVariant;
|
|
215
|
+
size?: import("../../index.ts").BadgeSize;
|
|
216
|
+
dot?: boolean;
|
|
217
|
+
pulse?: boolean;
|
|
218
|
+
icon?: import("../../index.ts").IconName;
|
|
205
219
|
innerHTML?: string | undefined | undefined;
|
|
206
220
|
class?: import("vue").ClassValue;
|
|
207
221
|
style?: import("vue").StyleValue;
|
|
@@ -394,13 +408,13 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
394
408
|
ref?: import("vue").VNodeRef | undefined;
|
|
395
409
|
ref_for?: boolean | undefined | undefined;
|
|
396
410
|
ref_key?: string | undefined | undefined;
|
|
397
|
-
context?: GridCellContext;
|
|
398
411
|
onVnodeBeforeMount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
399
412
|
onVnodeMounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
400
413
|
onVnodeBeforeUpdate?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
401
414
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
402
415
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
403
416
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
417
|
+
context?: GridCellContext;
|
|
404
418
|
}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
405
419
|
declare const _default: typeof __VLS_export;
|
|
406
420
|
export default _default;
|
package/dist/grid/data-grid.css
CHANGED
|
@@ -156,8 +156,9 @@
|
|
|
156
156
|
font-size: 0.75rem;
|
|
157
157
|
font-weight: var(--k-font-weight-medium, 500);
|
|
158
158
|
line-height: 1.2;
|
|
159
|
-
color: var(--k-badge-tone);
|
|
160
|
-
background: color-mix(in oklab, var(--k-badge-tone) 12%, transparent);
|
|
159
|
+
color: var(--k-badge-color, var(--k-badge-tone));
|
|
160
|
+
background: var(--k-badge-background, color-mix(in oklab, var(--k-badge-tone) 12%, transparent));
|
|
161
|
+
box-shadow: inset 0 0 0 1px var(--k-badge-border-color, transparent);
|
|
161
162
|
border-radius: var(--k-radius-full);
|
|
162
163
|
white-space: nowrap;
|
|
163
164
|
}
|
package/dist/grid/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ColDef, GridApi, ICellRendererParams } from 'ag-grid-community';
|
|
2
2
|
import type { Tone } from '../components/core/types';
|
|
3
|
+
import type { BadgeSize, BadgeVariant } from '../components/data/types';
|
|
3
4
|
import type { KMessages } from '../locale/types';
|
|
4
5
|
export type GridDensity = 'compact' | 'normal' | 'comfortable';
|
|
5
6
|
export type GridSelection = boolean | 'single' | 'multiple';
|
|
@@ -41,10 +42,13 @@ export interface DateCellParams {
|
|
|
41
42
|
relative?: boolean | Intl.RelativeTimeFormatOptions;
|
|
42
43
|
relativeWithin?: number;
|
|
43
44
|
}
|
|
44
|
-
export interface BadgeCellParams {
|
|
45
|
+
export interface BadgeCellParams<T = unknown> {
|
|
45
46
|
tones?: Record<string, Tone>;
|
|
46
47
|
labels?: Record<string, string>;
|
|
47
48
|
defaultTone?: Tone;
|
|
49
|
+
variant?: BadgeVariant;
|
|
50
|
+
size?: BadgeSize;
|
|
51
|
+
badgeClass?: string | ((value: unknown, data: T | undefined) => string | undefined);
|
|
48
52
|
}
|
|
49
53
|
export type ImageCellFit = 'cover' | 'contain';
|
|
50
54
|
export interface ImageCellParams<T = unknown> {
|
|
@@ -174,6 +174,19 @@
|
|
|
174
174
|
opacity: var(--k-calendar-unavailable-opacity, 0.6);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
.k-calendar-day.is-out-of-range .k-calendar-day-number,
|
|
178
|
+
.k-calendar-day.is-out-of-range:hover .k-calendar-day-number {
|
|
179
|
+
color: var(
|
|
180
|
+
--k-calendar-out-of-range-color,
|
|
181
|
+
var(--k-calendar-unavailable-color, var(--k-text-dimmed))
|
|
182
|
+
);
|
|
183
|
+
text-decoration: var(
|
|
184
|
+
--k-calendar-out-of-range-decoration,
|
|
185
|
+
var(--k-calendar-unavailable-decoration, line-through)
|
|
186
|
+
);
|
|
187
|
+
opacity: var(--k-calendar-out-of-range-opacity, var(--k-calendar-unavailable-opacity, 0.6));
|
|
188
|
+
}
|
|
189
|
+
|
|
177
190
|
.k-calendar.is-disabled {
|
|
178
191
|
opacity: 0.6;
|
|
179
192
|
pointer-events: none;
|
|
@@ -31,6 +31,13 @@
|
|
|
31
31
|
gap: 0.625rem 1.25rem;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
.k-checkbox-group-filled > .k-choice-group-items {
|
|
35
|
+
padding: var(--k-checkbox-group-padding, 0.75rem);
|
|
36
|
+
border: var(--k-checkbox-group-border, 0 solid transparent);
|
|
37
|
+
border-radius: var(--k-checkbox-group-radius, var(--k-radius-md));
|
|
38
|
+
background: var(--k-checkbox-group-background, var(--k-subtle));
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
.k-radio-group-card > .k-choice-group-items {
|
|
35
42
|
gap: 0.5rem;
|
|
36
43
|
}
|
|
@@ -203,6 +203,49 @@ html.k-root body {
|
|
|
203
203
|
transform: rotate(180deg);
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
@media (hover: hover) {
|
|
207
|
+
.k-shell.is-collapsed .k-sidebar-header:has(> .k-sidebar-brand:not(:empty)) {
|
|
208
|
+
position: relative;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.k-shell.is-collapsed
|
|
212
|
+
.k-sidebar-header:has(> .k-sidebar-brand:not(:empty))
|
|
213
|
+
> .k-sidebar-brand,
|
|
214
|
+
.k-shell.is-collapsed
|
|
215
|
+
.k-sidebar-header:has(> .k-sidebar-brand:not(:empty))
|
|
216
|
+
> .k-sidebar-collapse {
|
|
217
|
+
transition: opacity var(--k-duration) var(--k-ease);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.k-shell.is-collapsed
|
|
221
|
+
.k-sidebar-header:has(> .k-sidebar-brand:not(:empty))
|
|
222
|
+
> .k-sidebar-collapse {
|
|
223
|
+
position: absolute;
|
|
224
|
+
top: 50%;
|
|
225
|
+
left: 50%;
|
|
226
|
+
translate: -50% -50%;
|
|
227
|
+
opacity: 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.k-shell.is-collapsed
|
|
231
|
+
.k-sidebar-header:has(> .k-sidebar-brand:not(:empty)):is(
|
|
232
|
+
:hover,
|
|
233
|
+
:has(> .k-sidebar-collapse:focus-visible)
|
|
234
|
+
)
|
|
235
|
+
> .k-sidebar-brand {
|
|
236
|
+
opacity: 0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.k-shell.is-collapsed
|
|
240
|
+
.k-sidebar-header:has(> .k-sidebar-brand:not(:empty)):is(
|
|
241
|
+
:hover,
|
|
242
|
+
:has(> .k-sidebar-collapse:focus-visible)
|
|
243
|
+
)
|
|
244
|
+
> .k-sidebar-collapse {
|
|
245
|
+
opacity: 1;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
206
249
|
.k-shell.is-collapsed .k-navlink {
|
|
207
250
|
justify-content: center;
|
|
208
251
|
padding-inline: 0;
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.k-separator-label {
|
|
34
|
-
font-size: 0.75rem;
|
|
34
|
+
font-size: var(--k-separator-label-font-size, 0.75rem);
|
|
35
35
|
font-weight: var(--k-font-weight-medium, 500);
|
|
36
36
|
color: var(--k-text-muted);
|
|
37
37
|
white-space: nowrap;
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
font-size: var(--k-separator-heading-font-size, 0.9375rem);
|
|
97
97
|
font-weight: var(--k-font-weight-strong, 600);
|
|
98
98
|
line-height: 1.3;
|
|
99
|
-
color: var(--k-text);
|
|
99
|
+
color: var(--k-separator-heading-color, var(--k-text));
|
|
100
100
|
white-space: normal;
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -105,3 +105,12 @@
|
|
|
105
105
|
font-size: 0.8125rem;
|
|
106
106
|
line-height: 1.4;
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
.k-separator-heading.k-separator-center.has-label {
|
|
110
|
+
justify-content: center;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.k-separator-heading.k-separator-center .k-separator-text {
|
|
114
|
+
align-items: center;
|
|
115
|
+
text-align: center;
|
|
116
|
+
}
|
|
@@ -55,7 +55,30 @@
|
|
|
55
55
|
@container k-shell (min-width: 768px) {
|
|
56
56
|
.k-shell.is-collapsed .k-dashboard-search.k-command-trigger {
|
|
57
57
|
justify-content: center;
|
|
58
|
+
min-width: 0;
|
|
59
|
+
height: 1.875rem;
|
|
58
60
|
padding: 0;
|
|
61
|
+
color: var(--k-text-dimmed);
|
|
62
|
+
background: transparent;
|
|
63
|
+
border-color: transparent;
|
|
64
|
+
box-shadow: none;
|
|
65
|
+
transition:
|
|
66
|
+
background-color var(--k-duration) var(--k-ease),
|
|
67
|
+
color var(--k-duration) var(--k-ease),
|
|
68
|
+
scale var(--k-duration) var(--k-ease);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.k-shell.is-collapsed .k-dashboard-search.k-command-trigger:hover {
|
|
72
|
+
color: var(--k-text-muted);
|
|
73
|
+
background: var(--k-hover);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.k-shell.is-collapsed .k-dashboard-search.k-command-trigger:active {
|
|
77
|
+
scale: 0.985;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.k-shell.is-collapsed .k-dashboard-search.k-command-trigger:focus-visible {
|
|
81
|
+
box-shadow: var(--k-focus-ring);
|
|
59
82
|
}
|
|
60
83
|
|
|
61
84
|
.k-shell.is-collapsed .k-dashboard-search .k-command-trigger-text,
|
package/package.json
CHANGED