@threadlabs/looma 0.36.0 → 0.37.1
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/components/shared/icons.js +3 -0
- package/components/ui-avatar/ui-avatar.html +1 -1
- package/components/ui-avatar-group/ui-avatar-group.html +1 -1
- package/components/ui-button/ui-button.html +3 -12
- package/components/ui-card/ui-card.html +5 -5
- package/components/ui-checkbox/ui-checkbox.html +0 -6
- package/components/ui-color-picker/ui-color-picker.html +0 -9
- package/components/ui-combobox/ui-combobox.html +1 -13
- package/components/ui-cycle-button/ui-cycle-button.html +41 -0
- package/components/ui-cycle-button/ui-cycle-button.js +19 -0
- package/components/ui-dialog/ui-dialog.html +1 -1
- package/components/ui-icon/ui-icon.html +3 -0
- package/components/ui-icon-button/ui-icon-button.html +10 -14
- package/components/ui-input/ui-input.html +1 -16
- package/components/ui-input-group/ui-input-group.html +0 -10
- package/components/ui-menu/ui-menu.html +1 -1
- package/components/ui-popover/ui-popover.html +1 -1
- package/components/ui-radio/ui-radio.html +0 -6
- package/components/ui-select/ui-select.html +2 -8
- package/components/ui-switch/ui-switch.html +0 -6
- package/components/ui-tooltip/ui-tooltip.html +1 -1
- package/dist/index.js +47 -46
- package/docs/README.md +47 -8
- package/docs/card.html +2 -1
- package/docs/catalog.json +214 -39
- package/docs/customizer-render.mjs +8 -7
- package/docs/customizer.js +39 -21
- package/docs/theme.mjs +6 -5
- package/docs/value-editors.mjs +4 -3
- package/editor/icons.d.ts +3 -0
- package/editor/index.js +4 -1
- package/package.json +2 -2
- package/styles/ui-avatar-group.css +1 -1
- package/styles/ui-avatar.css +1 -1
- package/styles/ui-button.css +2 -14
- package/styles/ui-card.css +1 -1
- package/styles/ui-checkbox.css +0 -9
- package/styles/ui-color-picker.css +0 -13
- package/styles/ui-combobox.css +2 -28
- package/styles/ui-cycle-button.css +36 -0
- package/styles/ui-dialog.css +2 -2
- package/styles/ui-icon-button.css +6 -13
- package/styles/ui-input-group.css +0 -13
- package/styles/ui-input.css +2 -18
- package/styles/ui-menu.css +1 -1
- package/styles/ui-popover.css +1 -1
- package/styles/ui-radio.css +0 -9
- package/styles/ui-select.css +3 -10
- package/styles/ui-switch.css +0 -9
- package/styles/ui-tooltip.css +1 -1
- package/theme-system.css +19 -18
- package/tokens.css +20 -25
- package/vanilla/UiCycleButton.d.ts +29 -0
- package/vanilla/UiCycleButton.js +85 -0
- package/vanilla/UiIcon.js +1 -1
- package/vanilla/index.js +1 -0
- package/vue/UiAvatar.vue +1 -1
- package/vue/UiAvatarGroup.vue +1 -1
- package/vue/UiButton.vue +2 -11
- package/vue/UiCard.vue +5 -3
- package/vue/UiCheckbox.vue +0 -6
- package/vue/UiColorPicker.vue +0 -9
- package/vue/UiCombobox.vue +2 -26
- package/vue/UiCycleButton.d.ts +69 -0
- package/vue/UiCycleButton.js +2 -0
- package/vue/UiCycleButton.vue +403 -0
- package/vue/UiDialog.vue +6 -2
- package/vue/UiIcon.vue +22 -0
- package/vue/UiIconButton.vue +2 -16
- package/vue/UiInput.vue +1 -22
- package/vue/UiInputGroup.vue +0 -10
- package/vue/UiMenu.vue +3 -1
- package/vue/UiPopover.vue +3 -1
- package/vue/UiRadio.vue +0 -6
- package/vue/UiSelect.vue +2 -8
- package/vue/UiSwitch.vue +0 -6
- package/vue/UiTooltip.vue +3 -1
- package/vue/chunks/UiAffordanceScope.js +1 -1
- package/vue/chunks/UiAvatar.js +2 -2
- package/vue/chunks/UiAvatarGroup.js +2 -2
- package/vue/chunks/UiBadge.js +1 -1
- package/vue/chunks/UiBreadcrumbItem.js +1 -1
- package/vue/chunks/UiBreadcrumbs.js +1 -1
- package/vue/chunks/UiButton.js +3 -3
- package/vue/chunks/UiCallout.js +1 -1
- package/vue/chunks/UiCard.js +4 -4
- package/vue/chunks/UiCheckbox.js +2 -2
- package/vue/chunks/UiCluster.js +1 -1
- package/vue/chunks/UiColorPicker.js +2 -2
- package/vue/chunks/UiCombobox.js +2 -2
- package/vue/chunks/UiContainer.js +1 -1
- package/vue/chunks/UiContextMenu.js +1 -1
- package/vue/chunks/UiCover.js +1 -1
- package/vue/chunks/UiCurveEditor.js +1 -1
- package/vue/chunks/UiCycleButton.js +352 -0
- package/vue/chunks/UiDescriptionItem.js +1 -1
- package/vue/chunks/UiDescriptionList.js +1 -1
- package/vue/chunks/UiDialog.js +2 -2
- package/vue/chunks/UiDisclosure.js +1 -1
- package/vue/chunks/UiEditable.js +1 -1
- package/vue/chunks/UiEditorBlockActions.js +1 -1
- package/vue/chunks/UiEditorChipEditor.js +1 -1
- package/vue/chunks/UiEditorCodeLanguage.js +1 -1
- package/vue/chunks/UiEditorFootnoteEditor.js +1 -1
- package/vue/chunks/UiEditorImageToolbar.js +1 -1
- package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
- package/vue/chunks/UiEditorLinkCard.js +1 -1
- package/vue/chunks/UiEditorLinkForm.js +1 -1
- package/vue/chunks/UiEditorMentionMenu.js +1 -1
- package/vue/chunks/UiEditorMentionMenuItem.js +1 -1
- package/vue/chunks/UiEditorSlashMenu.js +1 -1
- package/vue/chunks/UiEditorSlashMenuGroup.js +1 -1
- package/vue/chunks/UiEditorSlashMenuItem.js +1 -1
- package/vue/chunks/UiEditorSurface.js +1 -1
- package/vue/chunks/UiEditorTableContextMenu.js +1 -1
- package/vue/chunks/UiEditorTableOverlay.js +1 -1
- package/vue/chunks/UiEditorTableToolbar.js +1 -1
- package/vue/chunks/UiEditorToolbar.js +1 -1
- package/vue/chunks/UiFloatingActionButton.js +1 -1
- package/vue/chunks/UiFormField.js +1 -1
- package/vue/chunks/UiGrid.js +1 -1
- package/vue/chunks/UiIcon.js +70 -2
- package/vue/chunks/UiIconButton.js +4 -4
- package/vue/chunks/UiImage.js +1 -1
- package/vue/chunks/UiInput.js +2 -2
- package/vue/chunks/UiInputGroup.js +2 -2
- package/vue/chunks/UiLightEditor.js +1 -1
- package/vue/chunks/UiList.js +1 -1
- package/vue/chunks/UiListItem.js +1 -1
- package/vue/chunks/UiListbox.js +1 -1
- package/vue/chunks/UiMenu.js +2 -2
- package/vue/chunks/UiMenuGroup.js +1 -1
- package/vue/chunks/UiMenuItem.js +1 -1
- package/vue/chunks/UiMeter.js +1 -1
- package/vue/chunks/UiNavItem.js +1 -1
- package/vue/chunks/UiNumberInput.js +1 -1
- package/vue/chunks/UiPageHeader.js +1 -1
- package/vue/chunks/UiPopover.js +2 -2
- package/vue/chunks/UiRadio.js +2 -2
- package/vue/chunks/UiRadioGroup.js +1 -1
- package/vue/chunks/UiReel.js +1 -1
- package/vue/chunks/UiScrollArea.js +1 -1
- package/vue/chunks/UiSearchResultRow.js +1 -1
- package/vue/chunks/UiSearchShell.js +1 -1
- package/vue/chunks/UiSection.js +1 -1
- package/vue/chunks/UiSelect.js +2 -2
- package/vue/chunks/UiSeparator.js +1 -1
- package/vue/chunks/UiSidebar.js +1 -1
- package/vue/chunks/UiSlider.js +1 -1
- package/vue/chunks/UiSpinner.js +1 -1
- package/vue/chunks/UiStack.js +1 -1
- package/vue/chunks/UiStatusMessage.js +1 -1
- package/vue/chunks/UiSwatch.js +1 -1
- package/vue/chunks/UiSwitch.js +2 -2
- package/vue/chunks/UiSwitcher.js +1 -1
- package/vue/chunks/UiTable.js +1 -1
- package/vue/chunks/UiTabs.js +1 -1
- package/vue/chunks/UiText.js +1 -1
- package/vue/chunks/UiTextarea.js +1 -1
- package/vue/chunks/UiToast.js +1 -1
- package/vue/chunks/UiToastRegion.js +1 -1
- package/vue/chunks/UiTooltip.js +2 -2
- package/vue/chunks/UiTree.js +1 -1
- package/vue/chunks/UiTreeItem.js +1 -1
- package/vue/chunks/props.js +12 -1
- package/vue/components.css +76 -181
- package/vue/editor/index.js +68 -0
- package/vue/index.d.ts +1 -0
- package/vue/index.js +2 -1
package/vue/UiCard.vue
CHANGED
|
@@ -51,7 +51,7 @@ const propValidityContract = {
|
|
|
51
51
|
required: false,
|
|
52
52
|
target: { attribute: 'tone' },
|
|
53
53
|
description:
|
|
54
|
-
'accent, info, success, warning and danger add a quiet semantic surface without changing card geometry. Row highlights follow the
|
|
54
|
+
'accent, info, success, warning and danger add a quiet semantic surface without changing card geometry. Row highlights follow the surface hue; action\n controls retain their own intent.',
|
|
55
55
|
values: ['neutral', 'accent', 'info', 'success', 'warning', 'danger'],
|
|
56
56
|
default: 'neutral',
|
|
57
57
|
},
|
|
@@ -60,7 +60,7 @@ const propValidityContract = {
|
|
|
60
60
|
required: false,
|
|
61
61
|
target: { attribute: 'treatment' },
|
|
62
62
|
description:
|
|
63
|
-
'How much of the theme\'s decorative material the surface expresses. standard preserves its restrained treatment; expressive uses the full material
|
|
63
|
+
'How much of the theme\'s decorative material the surface expresses. standard preserves its restrained treatment; expressive uses the full material\n treatment. This does not add elevation or require glass.',
|
|
64
64
|
values: ['standard', 'expressive'],
|
|
65
65
|
default: 'standard',
|
|
66
66
|
},
|
|
@@ -329,7 +329,9 @@ const hostState = computed(() =>
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
:global(:scope[data-ui-card-state~="treatment=expressive"]:where([data-hn-ui-card])) {
|
|
332
|
-
--_ui-panel-glass:
|
|
332
|
+
--_ui-panel-glass: calc(
|
|
333
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
334
|
+
);
|
|
333
335
|
--_ui-panel-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
334
336
|
--_ui-panel-rim: calc(
|
|
335
337
|
(var(--_ui-panel-separation) + var(--_ui-panel-glass) * 0.25) * 0.65 * 8px
|
package/vue/UiCheckbox.vue
CHANGED
|
@@ -574,12 +574,6 @@ useComponentHost(() => import('../components/ui-checkbox/ui-checkbox.js'), {
|
|
|
574
574
|
calc((var(--_row) - max(var(--_line), var(--_ui-checkbox-size, 1.125rem))) / 2)
|
|
575
575
|
) !important;
|
|
576
576
|
}
|
|
577
|
-
|
|
578
|
-
@media (pointer: coarse) {
|
|
579
|
-
:global(:scope[data-ui-checkbox-state~="size=sm"]:where([data-hn-ui-checkbox])) {
|
|
580
|
-
--_row: var(--ui-control-min-block-size);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
577
|
:global(:scope[hidden]:where([data-hn-ui-checkbox])) {
|
|
584
578
|
display: none !important;
|
|
585
579
|
}
|
package/vue/UiColorPicker.vue
CHANGED
|
@@ -409,14 +409,5 @@ useComponentHost(() => import('../components/ui-color-picker/ui-color-picker.js'
|
|
|
409
409
|
padding: 0 !important;
|
|
410
410
|
accent-color: var(--ui-accent-solid);
|
|
411
411
|
}
|
|
412
|
-
@media (pointer: coarse) {
|
|
413
|
-
:global(:scope) {
|
|
414
|
-
--_size: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
|
|
415
|
-
}
|
|
416
|
-
:global(:scope[data-ui-color-picker-state~="size=sm"]) {
|
|
417
|
-
--_size: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
|
|
418
|
-
--_font: var(--ui-font-size-md);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
412
|
}
|
|
422
413
|
</style>
|
package/vue/UiCombobox.vue
CHANGED
|
@@ -2378,20 +2378,8 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2378
2378
|
white-space: nowrap;
|
|
2379
2379
|
}
|
|
2380
2380
|
@media (pointer: coarse) {
|
|
2381
|
-
:global(:scope:where([data-hn-ui-combobox])) {
|
|
2382
|
-
--_row: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
|
|
2383
|
-
}
|
|
2384
|
-
:global(button:where([data-hn-ui-combobox])) {
|
|
2385
|
-
min-inline-size: 2.75rem;
|
|
2386
|
-
min-block-size: calc(var(--_row) - 2 * var(--ui-border-width));
|
|
2387
|
-
}
|
|
2388
|
-
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
2389
|
-
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
2390
|
-
:global(:scope[data-ui-combobox-state~="size=sm"]:where([data-hn-ui-combobox])) {
|
|
2391
|
-
--_row: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
|
|
2392
|
-
}
|
|
2393
2381
|
:global(:scope[data-ui-combobox-state~="size=sm"] input:where([data-hn-ui-combobox])) {
|
|
2394
|
-
font-size:
|
|
2382
|
+
font-size: var(--ui-font-size-md);
|
|
2395
2383
|
}
|
|
2396
2384
|
}
|
|
2397
2385
|
@media (forced-colors: active) {
|
|
@@ -2729,21 +2717,9 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2729
2717
|
white-space: nowrap;
|
|
2730
2718
|
}
|
|
2731
2719
|
@media (pointer: coarse) {
|
|
2732
|
-
:global(:where(.ui-combobox):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2733
|
-
--_row: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
|
|
2734
|
-
}
|
|
2735
|
-
:global(button:where(:scope, :scope *):where([data-hn-ui-combobox])) {
|
|
2736
|
-
min-inline-size: 2.75rem;
|
|
2737
|
-
min-block-size: calc(var(--_row) - 2 * var(--ui-border-width));
|
|
2738
|
-
}
|
|
2739
|
-
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
2740
|
-
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
2741
|
-
:global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2742
|
-
--_row: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
|
|
2743
|
-
}
|
|
2744
2720
|
:global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]
|
|
2745
2721
|
input:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2746
|
-
font-size:
|
|
2722
|
+
font-size: var(--ui-font-size-md);
|
|
2747
2723
|
}
|
|
2748
2724
|
}
|
|
2749
2725
|
@media (forced-colors: active) {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
import { type InputBindings } from './props.js';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
disabled: {
|
|
5
|
+
type: PropType<boolean | null>;
|
|
6
|
+
};
|
|
7
|
+
index: {
|
|
8
|
+
type: PropType<number | null>;
|
|
9
|
+
};
|
|
10
|
+
items: {
|
|
11
|
+
type: PropType<readonly ({
|
|
12
|
+
readonly value: string;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
readonly icon: string;
|
|
15
|
+
})[]>;
|
|
16
|
+
};
|
|
17
|
+
label: {
|
|
18
|
+
type: PropType<string | null>;
|
|
19
|
+
};
|
|
20
|
+
size: {
|
|
21
|
+
type: PropType<"sm" | "md" | "lg" | null>;
|
|
22
|
+
};
|
|
23
|
+
variant: {
|
|
24
|
+
type: PropType<"ghost" | "outline" | "solid" | null>;
|
|
25
|
+
};
|
|
26
|
+
"\0htmlNextInputStatus": {
|
|
27
|
+
type: PropType<InputBindings>;
|
|
28
|
+
};
|
|
29
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
+
change: (event: CustomEvent<{
|
|
31
|
+
readonly value: string;
|
|
32
|
+
readonly index: number;
|
|
33
|
+
}>) => any;
|
|
34
|
+
"update:index": (value: number) => any;
|
|
35
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
36
|
+
disabled: {
|
|
37
|
+
type: PropType<boolean | null>;
|
|
38
|
+
};
|
|
39
|
+
index: {
|
|
40
|
+
type: PropType<number | null>;
|
|
41
|
+
};
|
|
42
|
+
items: {
|
|
43
|
+
type: PropType<readonly ({
|
|
44
|
+
readonly value: string;
|
|
45
|
+
readonly label: string;
|
|
46
|
+
readonly icon: string;
|
|
47
|
+
})[]>;
|
|
48
|
+
};
|
|
49
|
+
label: {
|
|
50
|
+
type: PropType<string | null>;
|
|
51
|
+
};
|
|
52
|
+
size: {
|
|
53
|
+
type: PropType<"sm" | "md" | "lg" | null>;
|
|
54
|
+
};
|
|
55
|
+
variant: {
|
|
56
|
+
type: PropType<"ghost" | "outline" | "solid" | null>;
|
|
57
|
+
};
|
|
58
|
+
"\0htmlNextInputStatus": {
|
|
59
|
+
type: PropType<InputBindings>;
|
|
60
|
+
};
|
|
61
|
+
}>> & Readonly<{
|
|
62
|
+
onChange?: ((event: CustomEvent<{
|
|
63
|
+
readonly value: string;
|
|
64
|
+
readonly index: number;
|
|
65
|
+
}>) => any) | undefined;
|
|
66
|
+
"onUpdate:index"?: ((value: number) => any) | undefined;
|
|
67
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
68
|
+
declare const _default: typeof __VLS_export;
|
|
69
|
+
export default _default;
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
<!-- Generated by HTML Next 1.0.0-alpha.69 for Vue 3.5. Do not edit. -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
import { computed, getCurrentInstance, provide, ref, watchSyncEffect } from 'vue'
|
|
4
|
+
import type { PropType } from 'vue'
|
|
5
|
+
import {
|
|
6
|
+
checkHydratedRoot,
|
|
7
|
+
concat,
|
|
8
|
+
createDispatch,
|
|
9
|
+
cycleCheckedComputed,
|
|
10
|
+
initializedState,
|
|
11
|
+
nativeAttrs,
|
|
12
|
+
useComponentHost,
|
|
13
|
+
useReflectedProp,
|
|
14
|
+
warnUnless,
|
|
15
|
+
} from './host'
|
|
16
|
+
import { acceptsControllerWrite } from './props'
|
|
17
|
+
import {
|
|
18
|
+
BINDING_INPUTS_PROP,
|
|
19
|
+
checkedProp,
|
|
20
|
+
checkPropInput,
|
|
21
|
+
copyStateSeed,
|
|
22
|
+
evaluateInput,
|
|
23
|
+
type InputBindings,
|
|
24
|
+
inputComputed,
|
|
25
|
+
inputDefault,
|
|
26
|
+
inputRead,
|
|
27
|
+
propValidityState,
|
|
28
|
+
READY_INPUT,
|
|
29
|
+
requireInputStatus,
|
|
30
|
+
UNRESOLVED_INPUT,
|
|
31
|
+
vPropValidity,
|
|
32
|
+
vuePropInputs,
|
|
33
|
+
} from './props'
|
|
34
|
+
import UiIcon from './UiIcon.vue'
|
|
35
|
+
import UiIconButton from './UiIconButton.vue'
|
|
36
|
+
|
|
37
|
+
defineOptions({ inheritAttrs: false })
|
|
38
|
+
|
|
39
|
+
const propValidityContract = {
|
|
40
|
+
props: {
|
|
41
|
+
disabled: {
|
|
42
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
43
|
+
required: false,
|
|
44
|
+
target: { attribute: 'disabled' },
|
|
45
|
+
description: 'Prevents cycling while keeping the selected state visible.',
|
|
46
|
+
default: false,
|
|
47
|
+
},
|
|
48
|
+
index: {
|
|
49
|
+
type: { kind: 'terminal', name: 'number' },
|
|
50
|
+
required: false,
|
|
51
|
+
target: { attribute: 'index' },
|
|
52
|
+
description:
|
|
53
|
+
'Initial or externally selected zero-based state. The first state is the default.',
|
|
54
|
+
default: 0,
|
|
55
|
+
},
|
|
56
|
+
items: {
|
|
57
|
+
type: {
|
|
58
|
+
kind: 'list',
|
|
59
|
+
item: {
|
|
60
|
+
kind: 'object',
|
|
61
|
+
fields: [{ name: 'value', type: { kind: 'terminal', name: 'string' }, optional: false }, {
|
|
62
|
+
name: 'label',
|
|
63
|
+
type: { kind: 'terminal', name: 'string' },
|
|
64
|
+
optional: false,
|
|
65
|
+
}, { name: 'icon', type: { kind: 'terminal', name: 'string' }, optional: false }],
|
|
66
|
+
open: false,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: true,
|
|
70
|
+
target: { attribute: 'items' },
|
|
71
|
+
description:
|
|
72
|
+
'Ordered states with a value, readable label and Looma icon name. Activation advances to the next state and wraps.',
|
|
73
|
+
},
|
|
74
|
+
label: {
|
|
75
|
+
type: { kind: 'terminal', name: 'string' },
|
|
76
|
+
required: false,
|
|
77
|
+
target: { attribute: 'label' },
|
|
78
|
+
description:
|
|
79
|
+
'What the button changes, such as Appearance. The selected state is included in its accessible name.',
|
|
80
|
+
default: 'State',
|
|
81
|
+
},
|
|
82
|
+
size: {
|
|
83
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
84
|
+
required: false,
|
|
85
|
+
target: { attribute: 'size' },
|
|
86
|
+
description: 'Uses IconButton\'s compact visible sizes and adjustable invisible touch area.',
|
|
87
|
+
values: ['sm', 'md', 'lg'],
|
|
88
|
+
default: 'md',
|
|
89
|
+
},
|
|
90
|
+
variant: {
|
|
91
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
92
|
+
required: false,
|
|
93
|
+
target: { attribute: 'variant' },
|
|
94
|
+
description: 'Uses IconButton\'s standard emphasis.',
|
|
95
|
+
values: ['ghost', 'outline', 'solid'],
|
|
96
|
+
default: 'outline',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
} as const
|
|
100
|
+
const props = defineProps({
|
|
101
|
+
disabled: { type: null as unknown as PropType<boolean | null> },
|
|
102
|
+
index: { type: null as unknown as PropType<number | null> },
|
|
103
|
+
items: {
|
|
104
|
+
type: null as unknown as PropType<
|
|
105
|
+
readonly ({ readonly value: string; readonly label: string; readonly icon: string })[]
|
|
106
|
+
>,
|
|
107
|
+
},
|
|
108
|
+
label: { type: null as unknown as PropType<string | null> },
|
|
109
|
+
size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
|
|
110
|
+
variant: { type: null as unknown as PropType<'ghost' | 'outline' | 'solid' | null> },
|
|
111
|
+
[BINDING_INPUTS_PROP]: { type: null as unknown as PropType<InputBindings> },
|
|
112
|
+
})
|
|
113
|
+
const acceptedProps: Record<string, unknown> = {
|
|
114
|
+
disabled: false,
|
|
115
|
+
index: 0,
|
|
116
|
+
items: null,
|
|
117
|
+
label: 'State',
|
|
118
|
+
size: 'md',
|
|
119
|
+
variant: 'outline',
|
|
120
|
+
}
|
|
121
|
+
const inputTracking = vuePropInputs(acceptedProps, {
|
|
122
|
+
disabled: false,
|
|
123
|
+
index: 0,
|
|
124
|
+
label: 'State',
|
|
125
|
+
size: 'md',
|
|
126
|
+
variant: 'outline',
|
|
127
|
+
}, (name, value, source, values) => {
|
|
128
|
+
switch (name) {
|
|
129
|
+
case 'disabled':
|
|
130
|
+
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
131
|
+
case 'index':
|
|
132
|
+
return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
|
|
133
|
+
case 'items':
|
|
134
|
+
return checkPropInput(
|
|
135
|
+
value,
|
|
136
|
+
{
|
|
137
|
+
kind: 'list',
|
|
138
|
+
item: {
|
|
139
|
+
kind: 'object',
|
|
140
|
+
fields: [
|
|
141
|
+
{ name: 'value', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
142
|
+
{ name: 'label', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
143
|
+
{ name: 'icon', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
144
|
+
],
|
|
145
|
+
open: false,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
true,
|
|
149
|
+
false,
|
|
150
|
+
)
|
|
151
|
+
case 'label':
|
|
152
|
+
return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
|
|
153
|
+
case 'size':
|
|
154
|
+
return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
|
|
155
|
+
case 'variant':
|
|
156
|
+
return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
|
|
157
|
+
default:
|
|
158
|
+
return { ok: false }
|
|
159
|
+
}
|
|
160
|
+
}, () => {
|
|
161
|
+
void checkedProps.value
|
|
162
|
+
})
|
|
163
|
+
const propInputs = inputTracking.inputs
|
|
164
|
+
const checkedProps = computed(() => {
|
|
165
|
+
void inputTracking.version.value
|
|
166
|
+
return ({
|
|
167
|
+
disabled: propInputs.value<boolean | null>(
|
|
168
|
+
'disabled',
|
|
169
|
+
props['disabled'],
|
|
170
|
+
props[BINDING_INPUTS_PROP],
|
|
171
|
+
) as boolean,
|
|
172
|
+
index: propInputs.value<number | null>(
|
|
173
|
+
'index',
|
|
174
|
+
props['index'],
|
|
175
|
+
props[BINDING_INPUTS_PROP],
|
|
176
|
+
) as number,
|
|
177
|
+
items: propInputs.value<
|
|
178
|
+
readonly ({ readonly value: string; readonly label: string; readonly icon: string })[]
|
|
179
|
+
>('items', props['items'], props[BINDING_INPUTS_PROP]),
|
|
180
|
+
label: propInputs.value<string | null>(
|
|
181
|
+
'label',
|
|
182
|
+
props['label'],
|
|
183
|
+
props[BINDING_INPUTS_PROP],
|
|
184
|
+
) as string,
|
|
185
|
+
size: propInputs.value<'sm' | 'md' | 'lg' | null>(
|
|
186
|
+
'size',
|
|
187
|
+
props['size'],
|
|
188
|
+
props[BINDING_INPUTS_PROP],
|
|
189
|
+
) as 'sm' | 'md' | 'lg',
|
|
190
|
+
variant: propInputs.value<'ghost' | 'outline' | 'solid' | null>(
|
|
191
|
+
'variant',
|
|
192
|
+
props['variant'],
|
|
193
|
+
props[BINDING_INPUTS_PROP],
|
|
194
|
+
) as 'ghost' | 'outline' | 'solid',
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
const inputStatus = (name: string, handlesError: boolean) => {
|
|
198
|
+
void checkedProps.value
|
|
199
|
+
void inputTracking.version.value
|
|
200
|
+
return requireInputStatus(propInputs.status(name), handlesError)
|
|
201
|
+
}
|
|
202
|
+
void checkedProps.value
|
|
203
|
+
watchSyncEffect(() => {
|
|
204
|
+
void checkedProps.value
|
|
205
|
+
})
|
|
206
|
+
const reflectedProp = useReflectedProp()
|
|
207
|
+
const hydrationInstance = getCurrentInstance()
|
|
208
|
+
const emit = defineEmits<{
|
|
209
|
+
'update:index': [value: number]
|
|
210
|
+
change: [event: CustomEvent<{ readonly value: string; readonly index: number }>]
|
|
211
|
+
}>()
|
|
212
|
+
|
|
213
|
+
const root = ref<HTMLElement | null>(null)
|
|
214
|
+
const current = initializedState<number>(
|
|
215
|
+
() =>
|
|
216
|
+
evaluateInput(() => {
|
|
217
|
+
return inputRead(checkedProps.value.index, propInputs.status('index'))
|
|
218
|
+
}),
|
|
219
|
+
(next: unknown) => (typeof next === 'number' && Number.isFinite(next)),
|
|
220
|
+
copyStateSeed,
|
|
221
|
+
() =>
|
|
222
|
+
warnUnless(false, 'initializer:current', 'State `current` does not satisfy its declared type.'),
|
|
223
|
+
)
|
|
224
|
+
let selectedPrevious: { value: string; label: string; icon: string } | null = null
|
|
225
|
+
const selected: ReturnType<
|
|
226
|
+
typeof inputComputed<{ value: string; label: string; icon: string } | null>
|
|
227
|
+
> = inputComputed<{ value: string; label: string; icon: string } | null>(
|
|
228
|
+
() => {
|
|
229
|
+
return inputDefault(() =>
|
|
230
|
+
((objectValue: any, indexValue: any) =>
|
|
231
|
+
objectValue === Symbol.for('html-next.invalid-result')
|
|
232
|
+
|| indexValue === Symbol.for('html-next.invalid-result')
|
|
233
|
+
? Symbol.for('html-next.invalid-result')
|
|
234
|
+
: objectValue[indexValue])(
|
|
235
|
+
inputRead(checkedProps.value.items, propInputs.status('items')),
|
|
236
|
+
inputDefault(() => inputRead(current.value, declarationStatus('current')), () => 0),
|
|
237
|
+
), () =>
|
|
238
|
+
inputRead(checkedProps.value.items, propInputs.status('items'))[0]) as any
|
|
239
|
+
},
|
|
240
|
+
(read) => {
|
|
241
|
+
const value = cycleCheckedComputed(read)
|
|
242
|
+
return { get: () => value.value }
|
|
243
|
+
},
|
|
244
|
+
next =>
|
|
245
|
+
(next as unknown) === Symbol.for('html-next.invalid-result')
|
|
246
|
+
? selectedPrevious
|
|
247
|
+
: (selectedPrevious = next),
|
|
248
|
+
)
|
|
249
|
+
let guardedPrevious: any = null
|
|
250
|
+
const guarded = computed(() => {
|
|
251
|
+
const candidate: any = concat(
|
|
252
|
+
checkedProps.value.label,
|
|
253
|
+
': ',
|
|
254
|
+
selected.get()?.label ?? 'No choices',
|
|
255
|
+
)
|
|
256
|
+
if (candidate === Symbol.for('html-next.invalid-result')) return guardedPrevious
|
|
257
|
+
return guardedPrevious = candidate
|
|
258
|
+
})
|
|
259
|
+
provide('html-next:ui-cycle-button:current', current)
|
|
260
|
+
const declarationStatuses = { current: () => current.status() } as Record<
|
|
261
|
+
string,
|
|
262
|
+
() => typeof READY_INPUT
|
|
263
|
+
>
|
|
264
|
+
const declarationStatus = (name: string) => declarationStatuses[name]!()
|
|
265
|
+
current.start()
|
|
266
|
+
checkHydratedRoot('span', 'ui-cycle-button')
|
|
267
|
+
|
|
268
|
+
const isChangeDetail = (
|
|
269
|
+
detail: unknown,
|
|
270
|
+
): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
|
|
271
|
+
&& typeof (detail as Record<string, unknown>)['value'] === 'string'
|
|
272
|
+
&& (typeof (detail as Record<string, unknown>)['index'] === 'number'
|
|
273
|
+
&& Number.isFinite((detail as Record<string, unknown>)['index']))
|
|
274
|
+
&& Object.keys(detail as object).every((key) => ['value', 'index'].includes(key)))
|
|
275
|
+
const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
|
|
276
|
+
checks: {
|
|
277
|
+
change: isChangeDetail,
|
|
278
|
+
},
|
|
279
|
+
modeled: ['index'],
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
useComponentHost(() => import('../components/ui-cycle-button/ui-cycle-button.js'), {
|
|
283
|
+
root,
|
|
284
|
+
module: true,
|
|
285
|
+
dispatch,
|
|
286
|
+
acceptsState: (name: string, keys: readonly string[], value: unknown) =>
|
|
287
|
+
acceptsControllerWrite(
|
|
288
|
+
value,
|
|
289
|
+
({ current: { kind: 'terminal', name: 'number' } } as Record<string, any>)[name],
|
|
290
|
+
keys,
|
|
291
|
+
),
|
|
292
|
+
controllerSource: {
|
|
293
|
+
specifier: '../components/ui-cycle-button/ui-cycle-button.js',
|
|
294
|
+
definition: './components/ui-cycle-button/ui-cycle-button.html',
|
|
295
|
+
},
|
|
296
|
+
props: checkedProps,
|
|
297
|
+
inputs: propInputs,
|
|
298
|
+
inputTracking,
|
|
299
|
+
propInputs: (name: string) => {
|
|
300
|
+
const incoming = hydrationInstance?.vnode.props
|
|
301
|
+
const kebab = name.replace(/[A-Z]/g, (letter) => '-' + letter.toLowerCase())
|
|
302
|
+
return incoming !== null && incoming !== undefined
|
|
303
|
+
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
304
|
+
: null
|
|
305
|
+
},
|
|
306
|
+
propNames: ['disabled', 'index', 'items', 'label', 'size', 'variant'],
|
|
307
|
+
propValidity: (name: string) =>
|
|
308
|
+
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
309
|
+
state: { current },
|
|
310
|
+
computed: { selected },
|
|
311
|
+
availability: { current: () => declarationStatus('current'), selected: () => selected.status() },
|
|
312
|
+
})
|
|
313
|
+
</script>
|
|
314
|
+
|
|
315
|
+
<template>
|
|
316
|
+
<span
|
|
317
|
+
class="ui-cycle-button"
|
|
318
|
+
v-bind="nativeAttrs($attrs)"
|
|
319
|
+
data-hn
|
|
320
|
+
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
321
|
+
:data-ui-cycle-button-prop-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
|
|
322
|
+
:data-ui-cycle-button-prop-index="reflectedProp('index', 'index', checkedProps.index, undefined, false)"
|
|
323
|
+
:data-ui-cycle-button-prop-items="reflectedProp('items', 'items', checkedProps.items, undefined, false)"
|
|
324
|
+
:data-ui-cycle-button-prop-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
|
|
325
|
+
:data-ui-cycle-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
|
|
326
|
+
:data-ui-cycle-button-prop-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
|
|
327
|
+
ref="root"
|
|
328
|
+
><template
|
|
329
|
+
v-for="boundInput in [evaluateInput(
|
|
330
|
+
() =>
|
|
331
|
+
(concat(
|
|
332
|
+
inputRead(checkedProps.label, inputStatus('label', true)),
|
|
333
|
+
': ',
|
|
334
|
+
inputDefault(() => inputRead(selected.get(), selected.status())?.label, () => 'No choices'),
|
|
335
|
+
)) as any,
|
|
336
|
+
READY_INPUT,
|
|
337
|
+
)]"
|
|
338
|
+
><template
|
|
339
|
+
v-for="boundInputSnapshot in [evaluateInput(
|
|
340
|
+
() =>
|
|
341
|
+
(inputRead(checkedProps.disabled, inputStatus('disabled', true))
|
|
342
|
+
|| inputRead(checkedProps.items, inputStatus('items', true)).length < 2) as any,
|
|
343
|
+
READY_INPUT,
|
|
344
|
+
)]"
|
|
345
|
+
><UiIconButton
|
|
346
|
+
class="ui-icon-button"
|
|
347
|
+
tone="neutral"
|
|
348
|
+
aria-description="Activate to choose the next state."
|
|
349
|
+
:label="boundInput.value"
|
|
350
|
+
:title="guarded"
|
|
351
|
+
:size="checkedProps.size"
|
|
352
|
+
:variant="checkedProps.variant"
|
|
353
|
+
:disabled="boundInputSnapshot.value"
|
|
354
|
+
v-bind="{
|
|
355
|
+
[BINDING_INPUTS_PROP]: {
|
|
356
|
+
label: () => boundInput,
|
|
357
|
+
size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
|
|
358
|
+
variant: () => ({ value: checkedProps.variant, status: inputStatus('variant', true) }),
|
|
359
|
+
disabled: () => boundInputSnapshot,
|
|
360
|
+
},
|
|
361
|
+
}"
|
|
362
|
+
><template
|
|
363
|
+
v-for="boundInputSnapshot2 in [evaluateInput(
|
|
364
|
+
() => (inputDefault(() => inputRead(selected.get(), selected.status())?.icon, () => '')) as any,
|
|
365
|
+
READY_INPUT,
|
|
366
|
+
)]"
|
|
367
|
+
><UiIcon
|
|
368
|
+
class="ui-icon"
|
|
369
|
+
:name="boundInputSnapshot2.value"
|
|
370
|
+
v-bind="{ [BINDING_INPUTS_PROP]: { name: () => boundInputSnapshot2 } }"
|
|
371
|
+
/></template></UiIconButton></template></template></span>
|
|
372
|
+
</template>
|
|
373
|
+
|
|
374
|
+
<style scoped>
|
|
375
|
+
@scope (.ui-cycle-button) to ([data-hn]) {
|
|
376
|
+
:global(:scope) {
|
|
377
|
+
display: inline-flex !important;
|
|
378
|
+
align-items: center !important;
|
|
379
|
+
justify-content: center !important;
|
|
380
|
+
gap: 0 !important;
|
|
381
|
+
margin: 0 !important;
|
|
382
|
+
padding: 0 !important;
|
|
383
|
+
vertical-align: middle;
|
|
384
|
+
}
|
|
385
|
+
:global(:scope[hidden]) {
|
|
386
|
+
display: none !important;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
@scope ([data-slotted~="ui-cycle-button"]:not([data-hn])) to ([data-hn], [data-slotted]) {
|
|
390
|
+
:global(:where(.ui-cycle-button):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-cycle-button"])))) {
|
|
391
|
+
display: inline-flex !important;
|
|
392
|
+
align-items: center !important;
|
|
393
|
+
justify-content: center !important;
|
|
394
|
+
gap: 0 !important;
|
|
395
|
+
margin: 0 !important;
|
|
396
|
+
padding: 0 !important;
|
|
397
|
+
vertical-align: middle;
|
|
398
|
+
}
|
|
399
|
+
:global(:where(.ui-cycle-button)[hidden]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-cycle-button"])))) {
|
|
400
|
+
display: none !important;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
</style>
|
package/vue/UiDialog.vue
CHANGED
|
@@ -428,7 +428,9 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
428
428
|
overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
429
429
|
}
|
|
430
430
|
:global(:scope:where([data-hn-ui-dialog])) {
|
|
431
|
-
--_ui-material-glassiness:
|
|
431
|
+
--_ui-material-glassiness: calc(
|
|
432
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
433
|
+
);
|
|
432
434
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
433
435
|
--_ui-material-active: clamp(
|
|
434
436
|
0,
|
|
@@ -707,7 +709,9 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
707
709
|
overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
708
710
|
}
|
|
709
711
|
:global(:where(.ui-dialog):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-dialog"]))):where([data-hn-ui-dialog])) {
|
|
710
|
-
--_ui-material-glassiness:
|
|
712
|
+
--_ui-material-glassiness: calc(
|
|
713
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
714
|
+
);
|
|
711
715
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
712
716
|
--_ui-material-active: clamp(
|
|
713
717
|
0,
|
package/vue/UiIcon.vue
CHANGED
|
@@ -326,6 +326,17 @@ const shapes: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
|
|
|
326
326
|
{ tag: 'path', d: 'M12 7v4' },
|
|
327
327
|
],
|
|
328
328
|
minus: [{ tag: 'path', d: 'M5 12h14' }],
|
|
329
|
+
monitor: [{ tag: 'rect', width: '20', height: '14', x: '2', y: '3', rx: '2' }, {
|
|
330
|
+
tag: 'line',
|
|
331
|
+
x1: '8',
|
|
332
|
+
x2: '16',
|
|
333
|
+
y1: '21',
|
|
334
|
+
y2: '21',
|
|
335
|
+
}, { tag: 'line', x1: '12', x2: '12', y1: '17', y2: '21' }],
|
|
336
|
+
moon: [{
|
|
337
|
+
tag: 'path',
|
|
338
|
+
d: 'M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401',
|
|
339
|
+
}],
|
|
329
340
|
'notebook-pen': [
|
|
330
341
|
{ tag: 'path', d: 'M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4' },
|
|
331
342
|
{ tag: 'path', d: 'M2 6h4' },
|
|
@@ -413,6 +424,17 @@ const shapes: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
|
|
|
413
424
|
tag: 'path',
|
|
414
425
|
d: 'M14 12a4 4 0 0 1 0 8H6',
|
|
415
426
|
}, { tag: 'line', x1: '4', x2: '20', y1: '12', y2: '12' }],
|
|
427
|
+
sun: [
|
|
428
|
+
{ tag: 'circle', cx: '12', cy: '12', r: '4' },
|
|
429
|
+
{ tag: 'path', d: 'M12 2v2' },
|
|
430
|
+
{ tag: 'path', d: 'M12 20v2' },
|
|
431
|
+
{ tag: 'path', d: 'm4.93 4.93 1.41 1.41' },
|
|
432
|
+
{ tag: 'path', d: 'm17.66 17.66 1.41 1.41' },
|
|
433
|
+
{ tag: 'path', d: 'M2 12h2' },
|
|
434
|
+
{ tag: 'path', d: 'M20 12h2' },
|
|
435
|
+
{ tag: 'path', d: 'm6.34 17.66-1.41 1.41' },
|
|
436
|
+
{ tag: 'path', d: 'm19.07 4.93-1.41 1.41' },
|
|
437
|
+
],
|
|
416
438
|
superscript: [{ tag: 'path', d: 'm4 19 8-8' }, { tag: 'path', d: 'm12 19-8-8' }, {
|
|
417
439
|
tag: 'path',
|
|
418
440
|
d: 'M20 12h-4c0-1.5.442-2 1.5-2.5S20 8.334 20 7.002c0-.472-.17-.93-.484-1.29a2.105 2.105 0 0 0-2.617-.436c-.42.239-.738.614-.899 1.06',
|
package/vue/UiIconButton.vue
CHANGED
|
@@ -77,7 +77,7 @@ const propValidityContract = {
|
|
|
77
77
|
required: false,
|
|
78
78
|
target: { attribute: 'data-match-button' },
|
|
79
79
|
description:
|
|
80
|
-
'Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row\'s height,
|
|
80
|
+
'Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row\'s height, on mouse and\n touch alike. Leave it off for compact toolbar and inline icon buttons.',
|
|
81
81
|
default: false,
|
|
82
82
|
},
|
|
83
83
|
pending: {
|
|
@@ -116,7 +116,7 @@ const propValidityContract = {
|
|
|
116
116
|
required: false,
|
|
117
117
|
target: { attribute: 'size' },
|
|
118
118
|
description:
|
|
119
|
-
'Button and icon size together: sm is 1.75rem with a small icon, md is 2rem, and lg is 2.5rem with a large icon.
|
|
119
|
+
'Button and icon size together: sm is 1.75rem with a small icon, md is 2rem, and lg is 2.5rem with a large icon. Touch can use an invisible hit area sized\n by the adjustable control target preference.',
|
|
120
120
|
values: ['sm', 'md', 'lg'],
|
|
121
121
|
default: 'md',
|
|
122
122
|
},
|
|
@@ -841,20 +841,6 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
|
|
|
841
841
|
--_size: var(--ui-control-size-lg);
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
-
@media (pointer: coarse) {
|
|
845
|
-
:global(:scope[data-ui-icon-button-state~="matchButton"]:where([data-hn-ui-icon-button])) {
|
|
846
|
-
inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
|
|
847
|
-
min-inline-size: max(
|
|
848
|
-
var(--ui-icon-button-size, var(--_size)),
|
|
849
|
-
var(--ui-control-min-block-size)
|
|
850
|
-
);
|
|
851
|
-
min-block-size: max(
|
|
852
|
-
var(--ui-icon-button-size, var(--_size)),
|
|
853
|
-
var(--ui-control-min-block-size)
|
|
854
|
-
);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
844
|
:global(:scope[data-ui-icon-button-state~="round"]:where([data-hn-ui-icon-button])) {
|
|
859
845
|
border-radius: var(--ui-radius-round);
|
|
860
846
|
}
|