@xleddyl/443-components-vue 0.8.3 → 0.8.4
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 +20 -16
- package/dist/components/layout/Separator.vue +22 -7
- package/dist/components/layout/Separator.vue.d.ts +14 -4
- package/dist/components/layout/types.d.ts +1 -0
- package/dist/components/overlays/ConfirmDialog.vue.d.ts +2 -2
- package/dist/components/overlays/ConfirmHost.vue.d.ts +2 -2
- package/dist/components/templates/SettingsModal.vue.d.ts +2 -2
- package/dist/composables/useForm.d.ts +1 -1
- package/dist/composables/useForm.mjs +53 -9
- package/dist/grid/cells/DateCell.vue +7 -2
- package/dist/grid/types.d.ts +1 -0
- package/dist/internal/overlays/OverlayView.vue.d.ts +2 -2
- package/dist/styles/core/button.css +12 -6
- package/dist/styles/forms/calendar.css +8 -8
- package/dist/styles/layout/separator.css +49 -0
- package/dist/styles/shared.css +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,20 +110,22 @@ Input tokens, declared only on the outermost root so nested roots inherit them:
|
|
|
110
110
|
|
|
111
111
|
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
112
|
|
|
113
|
-
| Area
|
|
114
|
-
|
|
|
115
|
-
| Type
|
|
116
|
-
| Buttons
|
|
117
|
-
| Fields
|
|
118
|
-
| Overlays
|
|
119
|
-
| Tooltip
|
|
120
|
-
| Shell
|
|
121
|
-
| Switch
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
126
|
-
|
|
113
|
+
| Area | Tokens |
|
|
114
|
+
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
|
+
| Type | `--k-font-weight` (400), `--k-font-weight-medium` (500), `--k-font-weight-strong` (600), `--k-font-weight-display` (650) |
|
|
116
|
+
| 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) |
|
|
117
|
+
| Fields | `--k-field-padding-x` |
|
|
118
|
+
| 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) |
|
|
119
|
+
| Tooltip | `--k-tooltip-background`, `--k-tooltip-text`, `--k-tooltip-border`, `--k-tooltip-radius`, `--k-tooltip-shadow`, `--k-tooltip-padding` |
|
|
120
|
+
| Shell | `--k-sidebar-width` (15rem), `--k-sidebar-rail-width`, `--k-topbar-height` (3rem), `--k-shell-inset`, `--k-shell-padding`, `--k-shell-content` |
|
|
121
|
+
| Switch | `--k-switch-track-width`, `--k-switch-track-height`, `--k-switch-thumb-size` (md size) |
|
|
122
|
+
| Separator | `--k-separator-heading-font-size` (0.9375rem) |
|
|
123
|
+
| Calendar | `--k-calendar-day-radius`, `--k-calendar-unavailable-color`, `--k-calendar-unavailable-decoration` (line-through), `--k-calendar-unavailable-opacity` (0.6) |
|
|
124
|
+
| Badge | `--k-badge-radius`, `--k-badge-font`, `--k-badge-font-size`, `--k-badge-font-weight`, `--k-badge-text-transform`, `--k-badge-letter-spacing` |
|
|
125
|
+
| 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` |
|
|
126
|
+
| Charts | `--k-chart-1` to `--k-chart-8` (series palette) |
|
|
127
|
+
|
|
128
|
+
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`).
|
|
127
129
|
|
|
128
130
|
Contrast is part of the tokens: `--k-text-muted` is the lightest text color (4.5:1), `--k-text-dimmed` is for icons and decoration (3:1), `--k-ring` is an opaque focus color (3:1 on every surface), and `--k-danger-text`, `--k-success-text`, `--k-warning-text`, `--k-info-text` color status text (4.5:1, also on soft tints). Every preset sets them for light and dark; keep the same ratios when you override them.
|
|
129
131
|
|
|
@@ -247,6 +249,8 @@ Issues are keyed by their first path segment and by their full dotted path (`blo
|
|
|
247
249
|
|
|
248
250
|
Built-in messages follow the active language. `messages` overrides them for one form.
|
|
249
251
|
|
|
252
|
+
`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
|
+
|
|
250
254
|
`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.
|
|
251
255
|
|
|
252
256
|
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.
|
|
@@ -326,7 +330,7 @@ Composables: `useTheme`, `usePreset`, `useForm`, `useField`, `useFieldControl`,
|
|
|
326
330
|
- `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.
|
|
327
331
|
- `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.
|
|
328
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`.
|
|
329
|
-
- `Separator` takes `description` (or `#description`) under its label, and an `#actions` slot rendered next to them (a small add or edit button).
|
|
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; `--k-separator-heading-font-size` (0.9375rem) sizes the heading.
|
|
330
334
|
- `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).
|
|
331
335
|
- `Tabs` items take `dot: true` for a small indicator without a number (`dotTone`, default `danger`; `dotLabel` is the hidden text, default "Needs attention").
|
|
332
336
|
- `DropdownMenu` takes `matchTriggerWidth` (the menu is at least as wide as its trigger) and `minWidth` (a CSS length).
|
|
@@ -635,7 +639,7 @@ Accessibility related props and defaults:
|
|
|
635
639
|
- `DataGrid` sort is a model: `v-model:sort` (`{ column, direction } | null`) sets the sorted column from outside (server side sort, a sort restored from the URL) and follows header clicks. Leave it unset for an uncontrolled grid. `sortChange` still fires with `serverSort`.
|
|
636
640
|
- `DataGrid` takes `rowHeight` and `headerHeight` (pixels) for an exact row size on top of `density`, and `headerText: (field, column) => string | undefined` to name every column that has a `field` and no `headerName` (from your i18n).
|
|
637
641
|
- `DataGrid` `filterable` registers the AG Grid text, number and date filters (`registerGridFilterModules()` does it without the prop) and turns `filter` on for every column. `filterChange(model, event)` fires with `api.getFilterModel()` whenever a column filter changes, also when the filters come from `gridOptions` or your own registered modules.
|
|
638
|
-
- `DateCell` takes `relative: true` (or `Intl.RelativeTimeFormatOptions`) in `cellRendererParams` for "3 days ago"; the absolute date stays in the `title`.
|
|
642
|
+
- `DateCell` takes `relative: true` (or `Intl.RelativeTimeFormatOptions`) in `cellRendererParams` for "3 days ago"; the absolute date stays in the `title`. `relativeWithin` (milliseconds, default unset: always relative) shows the absolute date instead once the value is further than that from now, in the past or the future (`relativeWithin: 7 * 86_400_000` keeps "3 days ago" and prints older dates in full).
|
|
639
643
|
- `DataGrid` takes `gridOptions` for any AG Grid option it does not wrap (`rowHeight`, `onCellEditingStopped`, `onFilterChanged`, ...). A prop of `DataGrid` wins only when it is set: `getRowId`, `rowSelection` (when `selectable` is off), `autoSizeStrategy` (also `undefined` to turn it off), `tooltipShowDelay`, `overlayNoRowsTemplate` and `overlayLoadingTemplate` from `gridOptions` are used otherwise; `defaultColDef` and `localeText` are merged over the component defaults, and `context` is merged under the cell context. Handlers from both run.
|
|
640
644
|
- `DataGrid` row ids: `getRowId: (params) => string` (wins), `rowIdKey` (a field of the row), or `gridOptions.getRowId`.
|
|
641
645
|
- `DataGrid` `fill` makes the grid, with its toolbar and footer, fill its parent (a flex or grid item with `flex: 1; min-height: 0`, or `height: 100%` in a block with a height) instead of the fixed `height`. Ignored with `autoHeight`.
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="k-separator"
|
|
4
|
-
:class="[
|
|
4
|
+
:class="[
|
|
5
|
+
`k-separator-${orientation}`,
|
|
6
|
+
{ 'k-separator-heading': isHeading, 'has-label': hasContent, 'no-lines': !lines }
|
|
7
|
+
]"
|
|
5
8
|
:role="plain ? 'none' : 'separator'"
|
|
6
9
|
:aria-orientation="!plain && orientation === 'vertical' ? 'vertical' : void 0"
|
|
7
10
|
>
|
|
8
|
-
<span v-if="hasText" class="k-separator-text">
|
|
9
|
-
<
|
|
11
|
+
<component :is="isHeading ? 'div' : 'span'" v-if="hasText" class="k-separator-text">
|
|
12
|
+
<component
|
|
13
|
+
:is="isHeading ? `h${level}` : 'span'"
|
|
14
|
+
v-if="label || $slots.default"
|
|
15
|
+
class="k-separator-label"
|
|
16
|
+
>
|
|
10
17
|
<slot>{{ label }}</slot>
|
|
11
|
-
</
|
|
12
|
-
<
|
|
18
|
+
</component>
|
|
19
|
+
<component
|
|
20
|
+
:is="isHeading ? 'p' : 'span'"
|
|
21
|
+
v-if="description || $slots.description"
|
|
22
|
+
class="k-separator-description"
|
|
23
|
+
>
|
|
13
24
|
<slot name="description">{{ description }}</slot>
|
|
14
|
-
</
|
|
15
|
-
</
|
|
25
|
+
</component>
|
|
26
|
+
</component>
|
|
16
27
|
<span v-if="$slots.actions" class="k-separator-actions">
|
|
17
28
|
<slot name="actions" />
|
|
18
29
|
</span>
|
|
@@ -23,6 +34,9 @@
|
|
|
23
34
|
import { computed, useSlots } from "vue";
|
|
24
35
|
const props = defineProps({
|
|
25
36
|
orientation: { type: String, required: false, default: "horizontal" },
|
|
37
|
+
variant: { type: String, required: false, default: "label" },
|
|
38
|
+
lines: { type: Boolean, required: false, default: true },
|
|
39
|
+
level: { type: Number, required: false, default: 3 },
|
|
26
40
|
label: { type: String, required: false },
|
|
27
41
|
description: { type: String, required: false },
|
|
28
42
|
decorative: { type: Boolean, required: false }
|
|
@@ -32,5 +46,6 @@ const hasText = computed(
|
|
|
32
46
|
() => Boolean(props.label || slots.default || props.description || slots.description)
|
|
33
47
|
);
|
|
34
48
|
const hasContent = computed(() => Boolean(hasText.value || slots.actions));
|
|
49
|
+
const isHeading = computed(() => props.variant === "heading" && props.orientation === "horizontal");
|
|
35
50
|
const plain = computed(() => props.decorative || hasContent.value);
|
|
36
51
|
</script>
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import type { HeadingLevel, SeparatorVariant } from './types';
|
|
2
|
+
declare var __VLS_13: {}, __VLS_21: {}, __VLS_23: {};
|
|
2
3
|
type __VLS_Slots = {} & {
|
|
3
|
-
default?: (props: typeof
|
|
4
|
+
default?: (props: typeof __VLS_13) => any;
|
|
4
5
|
} & {
|
|
5
|
-
description?: (props: typeof
|
|
6
|
+
description?: (props: typeof __VLS_21) => any;
|
|
6
7
|
} & {
|
|
7
|
-
actions?: (props: typeof
|
|
8
|
+
actions?: (props: typeof __VLS_23) => any;
|
|
8
9
|
};
|
|
9
10
|
declare const __VLS_base: import("vue").DefineComponent<{
|
|
10
11
|
orientation?: "horizontal" | "vertical";
|
|
12
|
+
variant?: SeparatorVariant;
|
|
13
|
+
lines?: boolean;
|
|
14
|
+
level?: HeadingLevel;
|
|
11
15
|
label?: string;
|
|
12
16
|
description?: string;
|
|
13
17
|
decorative?: boolean;
|
|
@@ -205,6 +209,9 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
205
209
|
ref_key?: string | undefined | undefined;
|
|
206
210
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
207
211
|
orientation?: "horizontal" | "vertical";
|
|
212
|
+
variant?: SeparatorVariant;
|
|
213
|
+
lines?: boolean;
|
|
214
|
+
level?: HeadingLevel;
|
|
208
215
|
label?: string;
|
|
209
216
|
description?: string;
|
|
210
217
|
decorative?: boolean;
|
|
@@ -402,6 +409,9 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
402
409
|
ref_key?: string | undefined | undefined;
|
|
403
410
|
}> & Readonly<{}>, {
|
|
404
411
|
orientation: "horizontal" | "vertical";
|
|
412
|
+
variant: SeparatorVariant;
|
|
413
|
+
level: HeadingLevel;
|
|
414
|
+
lines: boolean;
|
|
405
415
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
406
416
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
407
417
|
declare const _default: typeof __VLS_export;
|
|
@@ -45,6 +45,7 @@ export interface AccordionItem {
|
|
|
45
45
|
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
|
+
export type SeparatorVariant = 'label' | 'heading';
|
|
48
49
|
export interface AppShellContext {
|
|
49
50
|
sidebarId: string;
|
|
50
51
|
collapsed: Readonly<{
|
|
@@ -26,6 +26,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
26
26
|
style?: import("vue").StyleValue;
|
|
27
27
|
results?: (string | number) | undefined;
|
|
28
28
|
placeholder?: string | undefined;
|
|
29
|
+
flush?: boolean;
|
|
29
30
|
dir?: string | undefined;
|
|
30
31
|
class?: import("vue").ClassValue;
|
|
31
32
|
role?: string | undefined;
|
|
@@ -220,7 +221,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
220
221
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
221
222
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
222
223
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
223
|
-
flush?: boolean;
|
|
224
224
|
sheet?: boolean;
|
|
225
225
|
onClose?: (() => any) | undefined;
|
|
226
226
|
onOpen?: (() => any) | undefined;
|
|
@@ -256,6 +256,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
256
256
|
style?: import("vue").StyleValue;
|
|
257
257
|
results?: (string | number) | undefined;
|
|
258
258
|
placeholder?: string | undefined;
|
|
259
|
+
flush?: boolean;
|
|
259
260
|
dir?: string | undefined;
|
|
260
261
|
class?: import("vue").ClassValue;
|
|
261
262
|
role?: string | undefined;
|
|
@@ -450,7 +451,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
450
451
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
451
452
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
452
453
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
453
|
-
flush?: boolean;
|
|
454
454
|
sheet?: boolean;
|
|
455
455
|
onClose?: (() => any) | undefined;
|
|
456
456
|
onOpen?: (() => any) | undefined;
|
|
@@ -16,6 +16,7 @@ declare const __VLS_export: import("vue").DefineComponent<Partial<NonNullable<{
|
|
|
16
16
|
readonly style?: import("vue").StyleValue;
|
|
17
17
|
readonly results?: (string | number) | undefined;
|
|
18
18
|
readonly placeholder?: string | undefined | undefined;
|
|
19
|
+
readonly flush?: boolean | undefined;
|
|
19
20
|
readonly dir?: string | undefined | undefined;
|
|
20
21
|
readonly class?: import("vue").ClassValue;
|
|
21
22
|
readonly role?: string | undefined | undefined;
|
|
@@ -210,7 +211,6 @@ declare const __VLS_export: import("vue").DefineComponent<Partial<NonNullable<{
|
|
|
210
211
|
readonly onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
211
212
|
readonly onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
212
213
|
readonly onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
213
|
-
readonly flush?: boolean | undefined;
|
|
214
214
|
readonly sheet?: boolean | undefined;
|
|
215
215
|
readonly onClose?: (() => any) | undefined;
|
|
216
216
|
readonly onOpen?: (() => any) | undefined;
|
|
@@ -242,6 +242,7 @@ declare const __VLS_export: import("vue").DefineComponent<Partial<NonNullable<{
|
|
|
242
242
|
readonly style?: import("vue").StyleValue;
|
|
243
243
|
readonly results?: (string | number) | undefined;
|
|
244
244
|
readonly placeholder?: string | undefined | undefined;
|
|
245
|
+
readonly flush?: boolean | undefined;
|
|
245
246
|
readonly dir?: string | undefined | undefined;
|
|
246
247
|
readonly class?: import("vue").ClassValue;
|
|
247
248
|
readonly role?: string | undefined | undefined;
|
|
@@ -436,7 +437,6 @@ declare const __VLS_export: import("vue").DefineComponent<Partial<NonNullable<{
|
|
|
436
437
|
readonly onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
437
438
|
readonly onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
438
439
|
readonly onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
439
|
-
readonly flush?: boolean | undefined;
|
|
440
440
|
readonly sheet?: boolean | undefined;
|
|
441
441
|
readonly onClose?: (() => any) | undefined;
|
|
442
442
|
readonly onOpen?: (() => any) | undefined;
|
|
@@ -42,6 +42,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
42
42
|
results?: (string | number) | undefined;
|
|
43
43
|
placeholder?: string | undefined;
|
|
44
44
|
description?: string;
|
|
45
|
+
flush?: boolean;
|
|
45
46
|
dir?: string | undefined;
|
|
46
47
|
class?: import("vue").ClassValue;
|
|
47
48
|
role?: string | undefined;
|
|
@@ -236,7 +237,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
236
237
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
237
238
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
238
239
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
239
|
-
flush?: boolean;
|
|
240
240
|
sheet?: boolean;
|
|
241
241
|
onCancel?: ((payload: Event) => void) | undefined;
|
|
242
242
|
rootClass?: unknown;
|
|
@@ -281,6 +281,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
281
281
|
results?: (string | number) | undefined;
|
|
282
282
|
placeholder?: string | undefined;
|
|
283
283
|
description?: string;
|
|
284
|
+
flush?: boolean;
|
|
284
285
|
dir?: string | undefined;
|
|
285
286
|
class?: import("vue").ClassValue;
|
|
286
287
|
role?: string | undefined;
|
|
@@ -475,7 +476,6 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
475
476
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
476
477
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
477
478
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
478
|
-
flush?: boolean;
|
|
479
479
|
sheet?: boolean;
|
|
480
480
|
onCancel?: ((payload: Event) => void) | undefined;
|
|
481
481
|
rootClass?: unknown;
|
|
@@ -61,7 +61,7 @@ export type FormWarningsFunction<V> = (values: V) => FormWarningsResult | Promis
|
|
|
61
61
|
export type FormWarnings<V> = StandardSchemaV1 | Readonly<Ref<StandardSchemaV1 | undefined>> | FormWarningsFunction<V>;
|
|
62
62
|
export type FormPath<V> = (keyof V & string) | (string & {});
|
|
63
63
|
export interface UseFormOptions<S extends FormSchema = FormSchema, V extends object = FormValues<S>> {
|
|
64
|
-
schema?: S
|
|
64
|
+
schema?: MaybeRefOrGetter<S>;
|
|
65
65
|
values?: MaybeRefOrGetter<V>;
|
|
66
66
|
validator?: MaybeRefOrGetter<StandardSchemaV1 | undefined>;
|
|
67
67
|
warnings?: FormWarnings<V>;
|
|
@@ -105,8 +105,8 @@ function replaceEntries(target, next, inScope = () => true) {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
export function useForm(options) {
|
|
108
|
-
const schema = options.schema ?? {};
|
|
109
|
-
const schemaNames = Object.keys(schema);
|
|
108
|
+
const schema = computed(() => toValue(options.schema) ?? {});
|
|
109
|
+
const schemaNames = computed(() => Object.keys(schema.value));
|
|
110
110
|
const external = options.values !== void 0;
|
|
111
111
|
const { t, locale } = useLocale();
|
|
112
112
|
const config = hasInjectionContext() && inject(FORM_CONFIG_KEY, null) || null;
|
|
@@ -123,19 +123,21 @@ export function useForm(options) {
|
|
|
123
123
|
};
|
|
124
124
|
const translateIssues = (issues, kind) => issues.map((issue) => {
|
|
125
125
|
const name = issue.path.map(String).join(".") || void 0;
|
|
126
|
-
const label = name ? schema[name]?.label : void 0;
|
|
126
|
+
const label = name ? schema.value[name]?.label : void 0;
|
|
127
127
|
return { ...issue, message: translate(issue.message, { name, label, kind }) };
|
|
128
128
|
});
|
|
129
129
|
const validateOn = options.validateOn ?? "submit";
|
|
130
130
|
const issueKey = options.issueKey ?? defaultIssueKey;
|
|
131
|
-
const initialValues = () => Object.fromEntries(
|
|
131
|
+
const initialValues = () => Object.fromEntries(
|
|
132
|
+
schemaNames.value.map((name) => [name, resolveInitial(schema.value[name])])
|
|
133
|
+
);
|
|
132
134
|
const internalValues = external ? void 0 : reactive(initialValues());
|
|
133
135
|
const target = () => external ? toValue(options.values) : internalValues;
|
|
134
136
|
let baseline = cloneValue(target());
|
|
135
137
|
const baselineVersion = ref(0);
|
|
136
138
|
const names = computed(() => {
|
|
137
|
-
if (!external) return schemaNames;
|
|
138
|
-
return [.../* @__PURE__ */ new Set([...schemaNames, ...Object.keys(target())])];
|
|
139
|
+
if (!external) return schemaNames.value;
|
|
140
|
+
return [.../* @__PURE__ */ new Set([...schemaNames.value, ...Object.keys(target())])];
|
|
139
141
|
});
|
|
140
142
|
const errors = reactive({});
|
|
141
143
|
const warnings = reactive({});
|
|
@@ -184,7 +186,7 @@ export function useForm(options) {
|
|
|
184
186
|
return evaluateValidator();
|
|
185
187
|
}
|
|
186
188
|
function evaluateRules(name) {
|
|
187
|
-
const definition = schema[name];
|
|
189
|
+
const definition = schema.value[name];
|
|
188
190
|
if (!definition) return void 0;
|
|
189
191
|
const value = readValue(name);
|
|
190
192
|
const fieldMessages = { ...messages.value, ...definition.messages };
|
|
@@ -394,6 +396,46 @@ export function useForm(options) {
|
|
|
394
396
|
},
|
|
395
397
|
{ deep: true }
|
|
396
398
|
);
|
|
399
|
+
function dropErrorsWithin(name) {
|
|
400
|
+
for (const source of [ruleErrors, manualErrors, issueErrors, touched]) {
|
|
401
|
+
for (const key of Object.keys(source)) {
|
|
402
|
+
if (isWithin(key, name)) delete source[key];
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
watch(
|
|
407
|
+
schemaNames,
|
|
408
|
+
(next, previous) => {
|
|
409
|
+
const added = next.filter((name) => !previous.includes(name));
|
|
410
|
+
const removed = previous.filter((name) => !next.includes(name));
|
|
411
|
+
if (!added.length && !removed.length) return;
|
|
412
|
+
if (internalValues) {
|
|
413
|
+
for (const name of removed) delete internalValues[name];
|
|
414
|
+
for (const name of added) internalValues[name] = resolveInitial(schema.value[name]);
|
|
415
|
+
}
|
|
416
|
+
for (const name of removed) {
|
|
417
|
+
if (names.value.includes(name)) continue;
|
|
418
|
+
if (!external) delete baseline[name];
|
|
419
|
+
snapshots.delete(name);
|
|
420
|
+
fieldRuns.delete(name);
|
|
421
|
+
dropErrorsWithin(name);
|
|
422
|
+
}
|
|
423
|
+
for (const name of added) {
|
|
424
|
+
if (!external) baseline[name] = cloneValue(readValue(name));
|
|
425
|
+
snapshots.set(name, cloneValue(readValue(name)));
|
|
426
|
+
}
|
|
427
|
+
baselineVersion.value++;
|
|
428
|
+
syncErrors();
|
|
429
|
+
},
|
|
430
|
+
{ flush: "sync" }
|
|
431
|
+
);
|
|
432
|
+
watch(
|
|
433
|
+
schema,
|
|
434
|
+
() => {
|
|
435
|
+
if (submitCount.value > 0) void validate();
|
|
436
|
+
},
|
|
437
|
+
{ deep: 2 }
|
|
438
|
+
);
|
|
397
439
|
watch(
|
|
398
440
|
() => toValue(options.validator),
|
|
399
441
|
() => {
|
|
@@ -425,7 +467,9 @@ export function useForm(options) {
|
|
|
425
467
|
});
|
|
426
468
|
}
|
|
427
469
|
return {
|
|
428
|
-
schema
|
|
470
|
+
get schema() {
|
|
471
|
+
return schema.value;
|
|
472
|
+
},
|
|
429
473
|
get values() {
|
|
430
474
|
return target();
|
|
431
475
|
},
|
|
@@ -447,7 +491,7 @@ export function useForm(options) {
|
|
|
447
491
|
setErrors,
|
|
448
492
|
clearErrors,
|
|
449
493
|
touch,
|
|
450
|
-
isRequired: (name) => Boolean(schema[name]?.required),
|
|
494
|
+
isRequired: (name) => Boolean(schema.value[name]?.required),
|
|
451
495
|
reset,
|
|
452
496
|
submit
|
|
453
497
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
v-if="formatted"
|
|
4
4
|
class="k-data-grid-date k-tabular"
|
|
5
5
|
:datetime="iso"
|
|
6
|
-
:title="
|
|
6
|
+
:title="isRelative ? absolute : void 0"
|
|
7
7
|
>{{ formatted }}</time
|
|
8
8
|
>
|
|
9
9
|
<EmptyCell v-else :context="cellContext" />
|
|
@@ -30,9 +30,14 @@ const absolute = computed(
|
|
|
30
30
|
date.value
|
|
31
31
|
) : ""
|
|
32
32
|
);
|
|
33
|
+
const isRelative = computed(() => {
|
|
34
|
+
if (!date.value || !props.params.relative) return false;
|
|
35
|
+
const within = props.params.relativeWithin;
|
|
36
|
+
return within === void 0 || Math.abs(Date.now() - date.value.getTime()) <= within;
|
|
37
|
+
});
|
|
33
38
|
const formatted = computed(() => {
|
|
34
39
|
const relative = props.params.relative;
|
|
35
|
-
if (!date.value || !relative) return absolute.value;
|
|
40
|
+
if (!date.value || !relative || !isRelative.value) return absolute.value;
|
|
36
41
|
return formatRelativeTime(
|
|
37
42
|
date.value,
|
|
38
43
|
locale.value,
|
package/dist/grid/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
11
11
|
results?: (string | number) | undefined;
|
|
12
12
|
placeholder?: string | undefined;
|
|
13
13
|
description?: string;
|
|
14
|
+
flush?: boolean;
|
|
14
15
|
dir?: string | undefined;
|
|
15
16
|
class?: import("vue").ClassValue;
|
|
16
17
|
role?: string | undefined;
|
|
@@ -207,7 +208,6 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
207
208
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
208
209
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
209
210
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
210
|
-
flush?: boolean;
|
|
211
211
|
sheet?: boolean;
|
|
212
212
|
onCancel?: ((payload: Event) => void) | undefined;
|
|
213
213
|
side?: import("../../index.ts").DrawerSide;
|
|
@@ -234,6 +234,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
234
234
|
results?: (string | number) | undefined;
|
|
235
235
|
placeholder?: string | undefined;
|
|
236
236
|
description?: string;
|
|
237
|
+
flush?: boolean;
|
|
237
238
|
dir?: string | undefined;
|
|
238
239
|
class?: import("vue").ClassValue;
|
|
239
240
|
role?: string | undefined;
|
|
@@ -430,7 +431,6 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
430
431
|
onVnodeUpdated?: (((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void) | ((vnode: import("vue").VNode, oldVNode: import("vue").VNode) => void)[]) | undefined;
|
|
431
432
|
onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
432
433
|
onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
|
|
433
|
-
flush?: boolean;
|
|
434
434
|
sheet?: boolean;
|
|
435
435
|
onCancel?: ((payload: Event) => void) | undefined;
|
|
436
436
|
side?: import("../../index.ts").DrawerSide;
|
|
@@ -141,22 +141,22 @@
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.k-btn-solid:hover:not(:disabled, [aria-disabled='true']) {
|
|
144
|
-
background: color-mix(in oklab, var(--k-btn-tone) 90%, black);
|
|
144
|
+
background: var(--k-btn-hover-background, color-mix(in oklab, var(--k-btn-tone) 90%, black));
|
|
145
145
|
box-shadow:
|
|
146
146
|
inset 0 1px 0 var(--k-btn-highlight, rgb(255 255 255 / 0.22)),
|
|
147
147
|
var(--k-btn-shadow, 0 2px 8px -2px color-mix(in oklab, var(--k-btn-tone) 60%, transparent));
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
.k-btn-solid:active:not(:disabled, [aria-disabled='true']) {
|
|
151
|
-
background: color-mix(in oklab, var(--k-btn-tone) 82%, black);
|
|
151
|
+
background: var(--k-btn-active-background, color-mix(in oklab, var(--k-btn-tone) 82%, black));
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
.k-btn-accent.k-btn-solid:hover:not(:disabled, [aria-disabled='true']) {
|
|
155
|
-
background: var(--k-accent-hover);
|
|
155
|
+
background: var(--k-btn-hover-background, var(--k-accent-hover));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
.k-btn-accent.k-btn-solid:active:not(:disabled, [aria-disabled='true']) {
|
|
159
|
-
background: var(--k-accent-press);
|
|
159
|
+
background: var(--k-btn-active-background, var(--k-accent-press));
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
.k-btn-neutral.k-btn-solid {
|
|
@@ -167,12 +167,18 @@
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
.k-btn-neutral.k-btn-solid:hover:not(:disabled, [aria-disabled='true']) {
|
|
170
|
-
background:
|
|
170
|
+
background: var(
|
|
171
|
+
--k-btn-hover-background,
|
|
172
|
+
color-mix(in oklab, var(--k-text) 86%, var(--k-surface))
|
|
173
|
+
);
|
|
171
174
|
box-shadow: inset 0 1px 0 var(--k-btn-highlight, rgb(255 255 255 / 0.14));
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
.k-btn-neutral.k-btn-solid:active:not(:disabled, [aria-disabled='true']) {
|
|
175
|
-
background:
|
|
178
|
+
background: var(
|
|
179
|
+
--k-btn-active-background,
|
|
180
|
+
color-mix(in oklab, var(--k-text) 80%, var(--k-surface))
|
|
181
|
+
);
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
.k-btn-soft {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
place-items: center;
|
|
62
62
|
width: 100%;
|
|
63
63
|
height: 100%;
|
|
64
|
-
border-radius: var(--k-radius-md);
|
|
64
|
+
border-radius: var(--k-calendar-day-radius, var(--k-radius-md));
|
|
65
65
|
color: var(--k-text-toned);
|
|
66
66
|
font-variant-numeric: tabular-nums;
|
|
67
67
|
transition:
|
|
@@ -134,14 +134,14 @@
|
|
|
134
134
|
|
|
135
135
|
.k-calendar-day.is-in-range:first-child::before,
|
|
136
136
|
.k-calendar-day.is-in-preview:first-child::before {
|
|
137
|
-
border-top-left-radius: var(--k-radius-md);
|
|
138
|
-
border-bottom-left-radius: var(--k-radius-md);
|
|
137
|
+
border-top-left-radius: var(--k-calendar-day-radius, var(--k-radius-md));
|
|
138
|
+
border-bottom-left-radius: var(--k-calendar-day-radius, var(--k-radius-md));
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
.k-calendar-day.is-in-range:last-child::before,
|
|
142
142
|
.k-calendar-day.is-in-preview:last-child::before {
|
|
143
|
-
border-top-right-radius: var(--k-radius-md);
|
|
144
|
-
border-bottom-right-radius: var(--k-radius-md);
|
|
143
|
+
border-top-right-radius: var(--k-calendar-day-radius, var(--k-radius-md));
|
|
144
|
+
border-bottom-right-radius: var(--k-calendar-day-radius, var(--k-radius-md));
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
.k-calendar-day.is-selected .k-calendar-day-number,
|
|
@@ -169,9 +169,9 @@
|
|
|
169
169
|
.k-calendar-day.is-unavailable .k-calendar-day-number,
|
|
170
170
|
.k-calendar-day.is-unavailable:hover .k-calendar-day-number {
|
|
171
171
|
background: transparent;
|
|
172
|
-
color: var(--k-text-dimmed);
|
|
173
|
-
text-decoration: line-through;
|
|
174
|
-
opacity: 0.6;
|
|
172
|
+
color: var(--k-calendar-unavailable-color, var(--k-text-dimmed));
|
|
173
|
+
text-decoration: var(--k-calendar-unavailable-decoration, line-through);
|
|
174
|
+
opacity: var(--k-calendar-unavailable-opacity, 0.6);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
.k-calendar.is-disabled {
|
|
@@ -56,3 +56,52 @@
|
|
|
56
56
|
font-size: 0.75rem;
|
|
57
57
|
color: var(--k-text-muted);
|
|
58
58
|
}
|
|
59
|
+
|
|
60
|
+
.k-separator.no-lines {
|
|
61
|
+
background: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.k-separator.has-label.no-lines {
|
|
65
|
+
justify-content: center;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.k-separator.has-label.no-lines::before,
|
|
69
|
+
.k-separator.has-label.no-lines::after,
|
|
70
|
+
.k-separator-heading.has-label::before,
|
|
71
|
+
.k-separator-heading.has-label::after {
|
|
72
|
+
display: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.k-separator-heading.has-label {
|
|
76
|
+
justify-content: flex-start;
|
|
77
|
+
padding-top: 0.75rem;
|
|
78
|
+
border-top: 1px solid var(--k-line);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.k-separator-heading.has-label.no-lines {
|
|
82
|
+
padding-top: 0;
|
|
83
|
+
border-top: 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.k-separator-heading .k-separator-text {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex: 1;
|
|
89
|
+
align-items: flex-start;
|
|
90
|
+
gap: 0.25rem;
|
|
91
|
+
text-align: start;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.k-separator-heading .k-separator-label {
|
|
95
|
+
margin: 0;
|
|
96
|
+
font-size: var(--k-separator-heading-font-size, 0.9375rem);
|
|
97
|
+
font-weight: var(--k-font-weight-strong, 600);
|
|
98
|
+
line-height: 1.3;
|
|
99
|
+
color: var(--k-text);
|
|
100
|
+
white-space: normal;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.k-separator-heading .k-separator-description {
|
|
104
|
+
margin: 0;
|
|
105
|
+
font-size: 0.8125rem;
|
|
106
|
+
line-height: 1.4;
|
|
107
|
+
}
|
package/dist/styles/shared.css
CHANGED
package/package.json
CHANGED