nuance-ui 0.2.16 → 0.2.18

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.
Files changed (60) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/alert.vue +1 -1
  3. package/dist/runtime/components/app-shell/app-shell-main.vue +1 -1
  4. package/dist/runtime/components/app-shell/app-shell.vue +1 -1
  5. package/dist/runtime/components/badge.d.vue.ts +4 -1
  6. package/dist/runtime/components/badge.vue +5 -2
  7. package/dist/runtime/components/badge.vue.d.ts +4 -1
  8. package/dist/runtime/components/button/button.module.css +1 -1
  9. package/dist/runtime/components/checkbox/checkbox.d.vue.ts +2 -2
  10. package/dist/runtime/components/checkbox/checkbox.vue +1 -1
  11. package/dist/runtime/components/checkbox/checkbox.vue.d.ts +2 -2
  12. package/dist/runtime/components/floating-indicator.d.vue.ts +20 -0
  13. package/dist/runtime/components/floating-indicator.vue +50 -0
  14. package/dist/runtime/components/floating-indicator.vue.d.ts +20 -0
  15. package/dist/runtime/components/index.d.ts +2 -0
  16. package/dist/runtime/components/link/lib.d.ts +2 -2
  17. package/dist/runtime/components/nav-link/nav-link.vue +1 -1
  18. package/dist/runtime/components/paper.vue +1 -1
  19. package/dist/runtime/components/roving-focus/lib/context.d.ts +2 -2
  20. package/dist/runtime/components/segmented-control.d.vue.ts +46 -0
  21. package/dist/runtime/components/segmented-control.vue +130 -0
  22. package/dist/runtime/components/segmented-control.vue.d.ts +46 -0
  23. package/dist/runtime/components/switch/switch.d.vue.ts +2 -2
  24. package/dist/runtime/components/switch/switch.vue +2 -2
  25. package/dist/runtime/components/switch/switch.vue.d.ts +2 -2
  26. package/dist/runtime/components/table/ui/table.vue +1 -1
  27. package/dist/runtime/components/theme-toggle.d.vue.ts +14 -0
  28. package/dist/runtime/components/theme-toggle.vue +27 -0
  29. package/dist/runtime/components/theme-toggle.vue.d.ts +14 -0
  30. package/dist/runtime/composables/index.d.ts +1 -0
  31. package/dist/runtime/composables/index.js +1 -0
  32. package/dist/runtime/composables/use-floating-indicator.d.ts +11 -0
  33. package/dist/runtime/composables/use-floating-indicator.js +30 -0
  34. package/dist/runtime/form/checkbox-field.d.vue.ts +2 -1
  35. package/dist/runtime/form/checkbox-field.vue +8 -6
  36. package/dist/runtime/form/checkbox-field.vue.d.ts +2 -1
  37. package/dist/runtime/form/checkbox-group-field.vue +1 -1
  38. package/dist/runtime/form/date-field.vue +1 -1
  39. package/dist/runtime/form/date-time-field.vue +1 -1
  40. package/dist/runtime/form/email-field.vue +1 -1
  41. package/dist/runtime/form/number-field.vue +1 -1
  42. package/dist/runtime/form/password-field.vue +1 -1
  43. package/dist/runtime/form/segmented-control-field.d.vue.ts +7 -0
  44. package/dist/runtime/form/segmented-control-field.vue +45 -0
  45. package/dist/runtime/form/segmented-control-field.vue.d.ts +7 -0
  46. package/dist/runtime/form/select-field.vue +1 -1
  47. package/dist/runtime/form/switch-field.d.vue.ts +2 -1
  48. package/dist/runtime/form/switch-field.vue +8 -6
  49. package/dist/runtime/form/switch-field.vue.d.ts +2 -1
  50. package/dist/runtime/form/switch-group-field.vue +1 -1
  51. package/dist/runtime/form/text-field.vue +1 -1
  52. package/dist/runtime/form/textarea-field.vue +1 -1
  53. package/dist/runtime/form/time-field.vue +1 -1
  54. package/dist/runtime/styles/colors.css +1 -1
  55. package/dist/runtime/styles/const.css +1 -1
  56. package/dist/runtime/styles/dark-theme.css +1 -1
  57. package/dist/runtime/types/theme.d.ts +3 -3
  58. package/dist/runtime/utils/color/get-color-var.js +1 -2
  59. package/dist/runtime/utils/color/parse-theme-color.js +1 -2
  60. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.0.0"
6
6
  },
7
- "version": "0.2.16",
7
+ "version": "0.2.18",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -88,5 +88,5 @@ const style = useVarsResolver((theme) => {
88
88
  </template>
89
89
 
90
90
  <style module>
91
- .root{--alert-radius:var(--radius-default);--alert-bg:var(--color-primary-light);--alert-bd:1px solid transparent;--alert-color:var(--color-primary-light-color);background-color:var(--alert-bg);border:var(--alert-bd);border-radius:var(--alert-radius);color:var(--alert-color);gap:var(--spacing-md);overflow:hidden;padding:var(--spacing-md) var(--spacing-md);position:relative}.body,.root{display:flex}.body{flex:1;flex-direction:column;gap:var(--spacing-xs)}.title{align-items:center;display:flex;font-size:var(--font-size-sm);font-weight:700;justify-content:space-between}.label{display:block;overflow:hidden;text-overflow:ellipsis}.icon{align-items:center;display:flex;height:1.25rem;justify-content:flex-start;line-height:1;margin-top:1px;width:1.25rem}.message{font-size:var(--font-size-sm);overflow:hidden;text-overflow:ellipsis}:where([data-mantine-color-scheme=light]) .message{color:var(--color-black)}:where([data-mantine-color-scheme=dark]) .message{color:var(--color-white)}.message:where([data-variant=filled]){color:var(--alert-color)}.message:where([data-variant=white]){color:var(--color-black)}.closeButton{color:var(--alert-color);height:20px;width:20px}
91
+ .root{--alert-radius:var(--radius-default);--alert-bg:var(--color-primary-light);--alert-bd:1px solid transparent;--alert-color:var(--color-primary-light-color);background-color:var(--alert-bg);border:var(--alert-bd);border-radius:var(--alert-radius);color:var(--alert-color);gap:var(--spacing-sm);overflow:hidden;padding:var(--spacing-sm);position:relative}.body,.root{display:flex}.body{flex:1;flex-direction:column;gap:var(--spacing-xs)}.title{align-items:center;display:flex;font-size:var(--font-size-sm);font-weight:700;justify-content:space-between}.label{display:block;overflow:hidden;text-overflow:ellipsis}.icon{align-items:center;display:flex;height:1.25rem;justify-content:flex-start;line-height:1;margin-top:1px;width:1.25rem}.message{font-size:var(--font-size-sm);overflow:hidden;text-overflow:ellipsis}:where([data-mantine-color-scheme=light]) .message{color:var(--color-black)}:where([data-mantine-color-scheme=dark]) .message{color:var(--color-white)}.message:where([data-variant=filled]){color:var(--alert-color)}.message:where([data-variant=white]){color:var(--color-black)}.closeButton{color:var(--alert-color);height:20px;width:20px}
92
92
  </style>
@@ -13,5 +13,5 @@ const { mod } = defineProps({
13
13
  </template>
14
14
 
15
15
  <style module>
16
- .root{display:flex;flex-direction:column;min-height:100dvh;padding-bottom:calc(var(--app-shell-footer-offset, 0rem) + var(--app-shell-padding));padding-inline-end:calc(var(--app-shell-aside-offset, 0rem) + var(--app-shell-padding));padding-top:calc(var(--app-shell-header-offset, 0rem) + var(--app-shell-padding));padding-inline-start:calc(var(--app-shell-navbar-offset, 0rem) + var(--app-shell-padding));transition-duration:var(--app-shell-transition-duration);transition-property:padding;transition-timing-function:var(--app-shell-transition-timing-function)}
16
+ .root{min-height:100dvh;padding-bottom:calc(var(--app-shell-footer-offset, 0rem) + var(--app-shell-padding));padding-inline-end:calc(var(--app-shell-aside-offset, 0rem) + var(--app-shell-padding));padding-top:calc(var(--app-shell-header-offset, 0rem) + var(--app-shell-padding));padding-inline-start:calc(var(--app-shell-navbar-offset, 0rem) + var(--app-shell-padding));transition-duration:var(--app-shell-transition-duration);transition-property:padding;transition-timing-function:var(--app-shell-transition-timing-function)}
17
17
  </style>
@@ -51,5 +51,5 @@ const style = useVarsResolver(() => ({
51
51
  </template>
52
52
 
53
53
  <style module>
54
- .root{--app-shell-padding:var(--spacing-sm);--app-shell-element-padding:.25rem;--app-shell-transition-duration:200ms;--app-shell-transition-timing-function:ease;--app-shell-navbar-width:rem(56px);--app-shell-navbar-offset:var(--app-shell-navbar-width);--app-shell-navbar-transform:none;--app-shell-aside-width:rem(56px);--app-shell-aside-offset:var(--app-shell-aside-width);--app-shell-aside-transform:none;--app-shell-header-height:rem(56px);--app-shell-header-offset:var(--app-shell-header-height);--app-shell-header-transform:none;--app-shell-footer-height:rem(100px);--app-shell-footer-offset:var(--app-shell-footer-height);--app-shell-footer-transform:none;@mixin where-light{--app-shell-border-color:var(--color-gray-3)}@mixin where-dark{--app-shell-border-color:var(--color-slate-8)}}
54
+ .root{--app-shell-padding:var(--spacing-sm);--app-shell-element-padding:.25rem;--app-shell-transition-duration:200ms;--app-shell-transition-timing-function:ease;--app-shell-navbar-width:rem(56px);--app-shell-navbar-offset:var(--app-shell-navbar-width);--app-shell-navbar-transform:none;--app-shell-aside-width:rem(56px);--app-shell-aside-offset:var(--app-shell-aside-width);--app-shell-aside-transform:none;--app-shell-header-height:rem(56px);--app-shell-header-offset:var(--app-shell-header-height);--app-shell-header-transform:none;--app-shell-footer-height:rem(100px);--app-shell-footer-offset:var(--app-shell-footer-height);--app-shell-footer-transform:none;@mixin where-light{--app-shell-border-color:var(--color-gray-3)}@mixin where-dark{--app-shell-border-color:var(--color-dark-8)}}
55
55
  </style>
@@ -1,8 +1,9 @@
1
1
  import type { AnyString, NuanceColor, NuanceGradient, NuanceRadius, NuanceSize } from '@nui/types';
2
+ import type { CSSProperties } from 'vue';
2
3
  import type { BoxProps } from './box.vue.js';
3
4
  export type BadgeVariant = 'filled' | 'light' | 'outline' | 'dot' | 'default' | 'gradient';
4
5
  export interface BadgeVars {
5
- root: '--badge-height' | '--badge-padding-x' | '--badge-fz' | '--badge-radius' | '--badge-bg' | '--badge-color' | '--badge-bd' | '--badge-dot-color';
6
+ root: '--badge-height' | '--badge-padding-x' | '--badge-fz' | '--badge-fw' | '--badge-radius' | '--badge-bg' | '--badge-color' | '--badge-bd' | '--badge-dot-color';
6
7
  }
7
8
  export interface BadgeProps extends BoxProps {
8
9
  /**
@@ -30,6 +31,8 @@ export interface BadgeProps extends BoxProps {
30
31
  icon?: string;
31
32
  /** Visual variant */
32
33
  variant?: BadgeVariant;
34
+ /** Font weight */
35
+ fw?: CSSProperties['font-weight'];
33
36
  }
34
37
  declare var __VLS_8: {}, __VLS_15: {}, __VLS_17: {};
35
38
  type __VLS_Slots = {} & {
@@ -9,7 +9,8 @@ const {
9
9
  color,
10
10
  fullWidth = false,
11
11
  circle,
12
- icon
12
+ icon,
13
+ fw
13
14
  } = defineProps({
14
15
  size: { type: [String, Object], required: false },
15
16
  circle: { type: Boolean, required: false },
@@ -19,6 +20,7 @@ const {
19
20
  fullWidth: { type: Boolean, required: false },
20
21
  icon: { type: String, required: false },
21
22
  variant: { type: String, required: false },
23
+ fw: { type: void 0, required: false },
22
24
  is: { type: null, required: false },
23
25
  mod: { type: [Object, Array, null], required: false }
24
26
  });
@@ -33,6 +35,7 @@ const style = useVarsResolver((theme) => {
33
35
  "--badge-height": getSize(size, "badge-height"),
34
36
  "--badge-padding-x": getSize(size, "badge-padding-x"),
35
37
  "--badge-fz": getSize(size, "badge-fz"),
38
+ "--badge-fw": fw,
36
39
  "--badge-radius": circle || radius === void 0 ? void 0 : getRadius(radius),
37
40
  "--badge-bg": color || variant ? background : void 0,
38
41
  "--badge-color": color || variant ? text : void 0,
@@ -77,5 +80,5 @@ const style = useVarsResolver((theme) => {
77
80
  </template>
78
81
 
79
82
  <style module>
80
- .root{--badge-height-xs:rem(16px);--badge-height-sm:rem(18px);--badge-height-md:rem(20px);--badge-height-lg:rem(26px);--badge-height-xl:rem(32px);--badge-fz-xs:rem(8px);--badge-fz-sm:rem(10px);--badge-fz-md:rem(12px);--badge-fz-lg:rem(14px);--badge-fz-xl:rem(16px);--badge-padding-x-xs:rem(6px);--badge-padding-x-sm:rem(8px);--badge-padding-x-md:rem(10px);--badge-padding-x-lg:rem(12px);--badge-padding-x-xl:rem(16px);--badge-height:var(--badge-height-md);--badge-fz:var(--badge-fz-md);--badge-padding-x:var(--badge-padding-x-md);--badge-radius:100%;--badge-lh:calc(var(--badge-height) - rem(2px));--badge-color:var(--color-white);--badge-bg:var(--color-primary-filled);--badge-border-width:1px;--badge-bd:var(--badge-border-width) solid transparent;align-items:center;background:var(--badge-bg);border:var(--badge-bd);border-radius:var(--badge-radius);color:var(--badge-color);cursor:default;display:inline-grid;font-size:var(--badge-fz);font-weight:700;height:var(--badge-height);justify-content:center;letter-spacing:.25px;line-height:var(--badge-lh);overflow:hidden;padding:0 var(--badge-padding-x);text-decoration:none;text-overflow:ellipsis;text-transform:uppercase;width:-moz-fit-content;width:fit-content;-webkit-tap-highlight-color:transparent}.root:where([data-with-left-section],[data-variant=dot]){grid-template-columns:auto 1fr;padding-left:calc(var(--badge-padding-x) - var(--spacing-xs)/2)}.root:where([data-with-right-section]){grid-template-columns:1fr auto;padding-right:calc(var(--badge-padding-x) - var(--spacing-xs)/2)}.root:where([data-with-left-section][data-with-right-section],[data-variant=dot][data-with-right-section]){grid-template-columns:auto 1fr auto;padding:0 calc(var(--spacing-xs)/2)}.root:where([data-block]){display:flex;width:100%}.root:where([data-circle]){display:flex;padding-inline:2px;width:var(--badge-height)}.root:where([data-variant=dot]){@mixin where-light{--badge-color:var(--color-black)}@mixin where-dark{--badge-color:var(--color-white)}}.dot{--badge-dot-size:calc(var(--badge-height)/2);background-color:var(--badge-dot-color,var(--badge-color));border-radius:var(--badge-dot-size);display:block;height:var(--badge-dot-size);margin-inline-end:calc(var(--badge-dot-size)/2);width:var(--badge-dot-size)}.label{cursor:inherit;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap}.section{--badge-section-margin:calc(var(--spacing-xs)/2);align-items:center;display:inline-flex;justify-content:center;max-height:calc(var(--badge-height) - var(--badge-border-width)*2)}.section:where([data-position=left]){margin-inline-end:var(--badge-section-margin)}.section:where([data-position=right]){margin-inline-start:var(--badge-section-margin)}
83
+ .root{--badge-height-xs:rem(16px);--badge-height-sm:rem(18px);--badge-height-md:rem(20px);--badge-height-lg:rem(26px);--badge-height-xl:rem(32px);--badge-fz-xs:rem(8px);--badge-fz-sm:rem(10px);--badge-fz-md:rem(12px);--badge-fz-lg:rem(14px);--badge-fz-xl:rem(16px);--badge-fw:400;--badge-padding-x-xs:rem(6px);--badge-padding-x-sm:rem(8px);--badge-padding-x-md:rem(10px);--badge-padding-x-lg:rem(12px);--badge-padding-x-xl:rem(16px);--badge-height:var(--badge-height-md);--badge-fz:var(--badge-fz-md);--badge-padding-x:var(--badge-padding-x-md);--badge-radius:100%;--badge-lh:calc(var(--badge-height) - rem(2px));--badge-color:var(--color-white);--badge-bg:var(--color-primary-filled);--badge-border-width:1px;--badge-bd:var(--badge-border-width) solid transparent;align-items:center;background:var(--badge-bg);border:var(--badge-bd);border-radius:var(--badge-radius);color:var(--badge-color);cursor:default;display:inline-grid;font-size:var(--badge-fz);font-weight:var(--badge-fw);height:var(--badge-height);justify-content:center;letter-spacing:.25px;line-height:var(--badge-lh);overflow:hidden;padding:0 var(--badge-padding-x);text-decoration:none;text-overflow:ellipsis;text-transform:uppercase;width:-moz-fit-content;width:fit-content;-webkit-tap-highlight-color:transparent}.root:where([data-with-left-section],[data-variant=dot]){grid-template-columns:auto 1fr;padding-left:calc(var(--badge-padding-x) - var(--spacing-xs)/2)}.root:where([data-with-right-section]){grid-template-columns:1fr auto;padding-right:calc(var(--badge-padding-x) - var(--spacing-xs)/2)}.root:where([data-with-left-section][data-with-right-section],[data-variant=dot][data-with-right-section]){grid-template-columns:auto 1fr auto;padding:0 calc(var(--spacing-xs)/2)}.root:where([data-block]){display:flex;width:100%}.root:where([data-circle]){display:flex;padding-inline:2px;width:var(--badge-height)}.root:where([data-variant=dot]){@mixin where-light{--badge-color:var(--color-black)}@mixin where-dark{--badge-color:var(--color-white)}}.dot{--badge-dot-size:calc(var(--badge-height)/2);background-color:var(--badge-dot-color,var(--badge-color));border-radius:var(--badge-dot-size);display:block;height:var(--badge-dot-size);margin-inline-end:calc(var(--badge-dot-size)/2);width:var(--badge-dot-size)}.label{cursor:inherit;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap}.section{--badge-section-margin:calc(var(--spacing-xs)/2);align-items:center;display:inline-flex;justify-content:center;max-height:calc(var(--badge-height) - var(--badge-border-width)*2)}.section:where([data-position=left]){margin-inline-end:var(--badge-section-margin)}.section:where([data-position=right]){margin-inline-start:var(--badge-section-margin)}
81
84
  </style>
@@ -1,8 +1,9 @@
1
1
  import type { AnyString, NuanceColor, NuanceGradient, NuanceRadius, NuanceSize } from '@nui/types';
2
+ import type { CSSProperties } from 'vue';
2
3
  import type { BoxProps } from './box.vue.js';
3
4
  export type BadgeVariant = 'filled' | 'light' | 'outline' | 'dot' | 'default' | 'gradient';
4
5
  export interface BadgeVars {
5
- root: '--badge-height' | '--badge-padding-x' | '--badge-fz' | '--badge-radius' | '--badge-bg' | '--badge-color' | '--badge-bd' | '--badge-dot-color';
6
+ root: '--badge-height' | '--badge-padding-x' | '--badge-fz' | '--badge-fw' | '--badge-radius' | '--badge-bg' | '--badge-color' | '--badge-bd' | '--badge-dot-color';
6
7
  }
7
8
  export interface BadgeProps extends BoxProps {
8
9
  /**
@@ -30,6 +31,8 @@ export interface BadgeProps extends BoxProps {
30
31
  icon?: string;
31
32
  /** Visual variant */
32
33
  variant?: BadgeVariant;
34
+ /** Font weight */
35
+ fw?: CSSProperties['font-weight'];
33
36
  }
34
37
  declare var __VLS_8: {}, __VLS_15: {}, __VLS_17: {};
35
38
  type __VLS_Slots = {} & {
@@ -1 +1 @@
1
- .root{--button-height-xs:rem(30px);--button-height-sm:rem(36px);--button-height-md:rem(42px);--button-height-lg:rem(50px);--button-height-xl:rem(60px);--button-height-compact-xs:rem(22px);--button-height-compact-sm:rem(26px);--button-height-compact-md:rem(30px);--button-height-compact-lg:rem(34px);--button-height-compact-xl:rem(40px);--button-padding-x-xs:rem(14px);--button-padding-x-sm:rem(18px);--button-padding-x-md:rem(22px);--button-padding-x-lg:rem(26px);--button-padding-x-xl:rem(32px);--button-padding-x-compact-xs:rem(7px);--button-padding-x-compact-sm:rem(8px);--button-padding-x-compact-md:rem(10px);--button-padding-x-compact-lg:rem(12px);--button-padding-x-compact-xl:rem(14px);--button-height:var(--button-height-sm);--button-padding-x:var(--button-padding-x-sm);--button-color:var(--color-white);--button-fz:var(--font-size-sm);--button-bg:var(--color-primary-filled);--button-radius:var(--radius-default);--button-hover:var(--color-primary-filled-hover);--button-spacing:0;--button-justify:center;--button-section-size:calc(var(--button-height) - 0.25rem);background:var(--button-bg);border:var(--button-bd,rem(1px) solid transparent);border-radius:var(--button-radius);color:var(--button-color,var(--color-white));cursor:pointer;display:inline-block;font-size:var(--button-fz);font-weight:600;height:var(--button-height,var(--button-height-sm));line-height:1;overflow:hidden;padding-inline:var(--button-padding-x,var(--button-padding-x-sm));position:relative;text-align:center;transition:background-color .2s ease-in,color .2s ease-in;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:auto}.root:where([data-with-left-section]){padding-inline-start:0}.root:where([data-with-right-section]){padding-inline-end:0}.root:where([data-variant=gradient-outline]){background-clip:padding-box,border-box;background-origin:border-box}.root:where(:disabled:not([data-loading])){background:var(--color-disabled);border:1px solid transparent;color:var(--color-disabled);cursor:not-allowed;transform:none}.root:before{border-radius:var(--button-radius,var(--radius-default));content:"";filter:blur(12px);inset:-1px;opacity:0;pointer-events:none;position:absolute;transform:translateY(-100%);transition:transform .15s ease,opacity .1s ease;@mixin where-light{background:var(--color-gray-1);color:var(--color-gray-5)}@mixin where-dark{background:var(--color-dark-6);color:var(--color-dark-3)}}.root:where([data-loading]){cursor:not-allowed;transform:none}.root:where([data-loading]):before{opacity:1;transform:translateY(0)}.root:where([data-loading]) .inner{opacity:0;transform:translateY(100%)}.root:hover:where(:not([data-loading],:disabled)){background:var(--button-hover);color:var(--button-color)}.root:hover:where(:not([data-loading],:disabled)):where([data-variant=gradient-outline]){color:#fff}.inner{gap:var(--button-spacing);justify-content:center;overflow:visible;transition:transform .15s ease,opacity .1s ease;width:100%}.inner,.label{align-items:center;display:flex;height:100%}.label{flex:1;justify-content:var(--button-justify);opacity:1;overflow:hidden;white-space:nowrap}.label:where([data-loading]){opacity:.2}.section{--section-pointer-events:none;align-items:center;display:flex;height:100%;justify-content:center;pointer-events:var(--section-pointer-events);width:var(--button-section-size)}.loader{left:calc(50% - var(--loader-size)/2);position:absolute;top:calc(50% - var(--loader-size)/2)}.group{--group-border-width:1px;display:flex}.group>:where(*):focus{position:relative;z-index:1}.group[data-orientation=horizontal]{flex-direction:row}.group[data-orientation=horizontal]>:where(*):not(:only-child):first-child{border-end-end-radius:0;border-inline-end-width:calc(var(--group-border-width)/2);border-start-end-radius:0}.group[data-orientation=horizontal]>:where(*):not(:only-child):last-child{border-end-start-radius:0;border-inline-start-width:calc(var(--group-border-width)/2);border-start-start-radius:0}.group[data-orientation=horizontal]>:where(*):not(:only-child):not(:first-child):not(:last-child){border-inline-width:calc(var(--group-border-width)/2);border-radius:0}.group[data-orientation=vertical]{flex-direction:column}.group[data-orientation=vertical]>:where(*):not(:only-child):first-child{border-bottom-width:calc(var(--group-border-width)/2);border-end-end-radius:0;border-end-start-radius:0}.group[data-orientation=vertical]>:where(*):not(:only-child):last-child{border-start-end-radius:0;border-start-start-radius:0;border-top-width:calc(var(--group-border-width)/2)}.group[data-orientation=vertical]>:where(*):not(:only-child):not(:first-child):not(:last-child){border-bottom-width:calc(var(--group-border-width)/2);border-radius:0;border-top-width:calc(var(--group-border-width)/2)}
1
+ .root{--button-height-xs:rem(30px);--button-height-sm:rem(36px);--button-height-md:rem(42px);--button-height-lg:rem(50px);--button-height-xl:rem(60px);--button-height-compact-xs:rem(22px);--button-height-compact-sm:rem(26px);--button-height-compact-md:rem(30px);--button-height-compact-lg:rem(34px);--button-height-compact-xl:rem(40px);--button-padding-x-xs:rem(14px);--button-padding-x-sm:rem(18px);--button-padding-x-md:rem(22px);--button-padding-x-lg:rem(26px);--button-padding-x-xl:rem(32px);--button-padding-x-compact-xs:rem(7px);--button-padding-x-compact-sm:rem(8px);--button-padding-x-compact-md:rem(10px);--button-padding-x-compact-lg:rem(12px);--button-padding-x-compact-xl:rem(14px);--button-height:var(--button-height-sm);--button-padding-x:var(--button-padding-x-sm);--button-color:var(--color-white);--button-fz:var(--font-size-sm);--button-bg:var(--color-primary-filled);--button-radius:var(--radius-default);--button-hover:var(--color-primary-filled-hover);--button-spacing:0;--button-justify:center;--button-section-size:calc(var(--button-height) - 0.25rem);background:var(--button-bg);border:var(--button-bd,rem(1px) solid transparent);border-radius:var(--button-radius);color:var(--button-color,var(--color-white));cursor:pointer;display:inline-block;font-size:var(--button-fz);font-weight:600;height:var(--button-height,var(--button-height-sm));line-height:1;overflow:hidden;padding-inline:var(--button-padding-x,var(--button-padding-x-sm));position:relative;text-align:center;transition:background-color .2s ease-in,color .2s ease-in;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:auto}.root:where([data-with-left-section]){padding-inline-start:0}.root:where([data-with-right-section]){padding-inline-end:0}.root:where([data-variant=gradient-outline]){background-clip:padding-box,border-box;background-origin:border-box}.root:where(:disabled:not([data-loading])){background:var(--color-disabled);border:1px solid transparent;color:var(--color-disabled-text);cursor:not-allowed;transform:none}.root:before{border-radius:var(--button-radius,var(--radius-default));content:"";filter:blur(12px);inset:-1px;opacity:0;pointer-events:none;position:absolute;transform:translateY(-100%);transition:transform .15s ease,opacity .1s ease;@mixin where-light{background:var(--color-gray-1);color:var(--color-gray-5)}@mixin where-dark{background:var(--color-dark-6);color:var(--color-dark-3)}}.root:where([data-loading]){cursor:not-allowed;transform:none}.root:where([data-loading]):before{opacity:1;transform:translateY(0)}.root:where([data-loading]) .inner{opacity:0;transform:translateY(100%)}.root:hover:where(:not([data-loading],:disabled)){background:var(--button-hover);color:var(--button-color)}.root:hover:where(:not([data-loading],:disabled)):where([data-variant=gradient-outline]){color:#fff}.inner{gap:var(--button-spacing);justify-content:center;overflow:visible;transition:transform .15s ease,opacity .1s ease;width:100%}.inner,.label{align-items:center;display:flex;height:100%}.label{flex:1;justify-content:var(--button-justify);opacity:1;overflow:hidden;white-space:nowrap}.label:where([data-loading]){opacity:.2}.section{--section-pointer-events:none;align-items:center;display:flex;height:100%;justify-content:center;pointer-events:var(--section-pointer-events);width:var(--button-section-size)}.loader{left:calc(50% - var(--loader-size)/2);position:absolute;top:calc(50% - var(--loader-size)/2)}.group{--group-border-width:1px;display:flex}.group>:where(*):focus{position:relative;z-index:1}.group[data-orientation=horizontal]{flex-direction:row}.group[data-orientation=horizontal]>:where(*):not(:only-child):first-child{border-end-end-radius:0;border-inline-end-width:calc(var(--group-border-width)/2);border-start-end-radius:0}.group[data-orientation=horizontal]>:where(*):not(:only-child):last-child{border-end-start-radius:0;border-inline-start-width:calc(var(--group-border-width)/2);border-start-start-radius:0}.group[data-orientation=horizontal]>:where(*):not(:only-child):not(:first-child):not(:last-child){border-inline-width:calc(var(--group-border-width)/2);border-radius:0}.group[data-orientation=vertical]{flex-direction:column}.group[data-orientation=vertical]>:where(*):not(:only-child):first-child{border-bottom-width:calc(var(--group-border-width)/2);border-end-end-radius:0;border-end-start-radius:0}.group[data-orientation=vertical]>:where(*):not(:only-child):last-child{border-start-end-radius:0;border-start-start-radius:0;border-top-width:calc(var(--group-border-width)/2)}.group[data-orientation=vertical]>:where(*):not(:only-child):not(:first-child):not(:last-child){border-bottom-width:calc(var(--group-border-width)/2);border-radius:0;border-top-width:calc(var(--group-border-width)/2)}
@@ -33,9 +33,9 @@ type __VLS_Slots = {} & {
33
33
  icon?: (props: typeof __VLS_14) => any;
34
34
  };
35
35
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
36
- "update:modelValue": (value: boolean | "indeterminate") => any;
36
+ "update:modelValue": (value: boolean | "indeterminate" | undefined) => any;
37
37
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
38
- "onUpdate:modelValue"?: ((value: boolean | "indeterminate") => any) | undefined;
38
+ "onUpdate:modelValue"?: ((value: boolean | "indeterminate" | undefined) => any) | undefined;
39
39
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
40
40
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
41
41
  declare const _default: typeof __VLS_export;
@@ -33,7 +33,7 @@ const {
33
33
  is: { type: null, required: false },
34
34
  mod: { type: [Object, Array, null], required: false }
35
35
  });
36
- const modelValue = defineModel({ type: [Boolean, String], ...{ default: false } });
36
+ const modelValue = defineModel({ type: [Boolean, String] });
37
37
  const ctx = useCheckboxGroupState();
38
38
  const checked = computed({
39
39
  get: () => {
@@ -33,9 +33,9 @@ type __VLS_Slots = {} & {
33
33
  icon?: (props: typeof __VLS_14) => any;
34
34
  };
35
35
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
36
- "update:modelValue": (value: boolean | "indeterminate") => any;
36
+ "update:modelValue": (value: boolean | "indeterminate" | undefined) => any;
37
37
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
38
- "onUpdate:modelValue"?: ((value: boolean | "indeterminate") => any) | undefined;
38
+ "onUpdate:modelValue"?: ((value: boolean | "indeterminate" | undefined) => any) | undefined;
39
39
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
40
40
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
41
41
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,20 @@
1
+ import type { BoxProps } from './box.vue.js';
2
+ export interface FloatingIndicatorProps extends BoxProps {
3
+ /**
4
+ * Target element over which the indicator is displayed.
5
+ * The indicator will be positioned to match the target's size and position.
6
+ */
7
+ target: HTMLElement | null | undefined;
8
+ /**
9
+ * Parent container element that must have `position: relative`.
10
+ * The indicator's position is calculated relative to this element.
11
+ */
12
+ parent: HTMLElement | null | undefined;
13
+ /** Component orientation */
14
+ orientation?: 'horizontal' | 'vertical';
15
+ /** Transition duration in ms or CSS time value @default `150` */
16
+ transitionDuration?: number | string;
17
+ }
18
+ declare const __VLS_export: import("vue").DefineComponent<FloatingIndicatorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FloatingIndicatorProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
@@ -0,0 +1,50 @@
1
+ <script setup>
2
+ import { useFloatingIndicator, useVarsResolver } from "@nui/composables";
3
+ import { shallowRef, watch } from "vue";
4
+ import Box from "./box.vue";
5
+ const {
6
+ is = "span",
7
+ mod,
8
+ target,
9
+ parent,
10
+ orientation = "horizontal",
11
+ transitionDuration: duration
12
+ } = defineProps({
13
+ target: { type: null, required: true },
14
+ parent: { type: null, required: true },
15
+ orientation: { type: String, required: false },
16
+ transitionDuration: { type: [Number, String], required: false },
17
+ is: { type: null, required: false },
18
+ mod: { type: [Object, Array, null], required: false }
19
+ });
20
+ const _target = shallowRef(target ?? null);
21
+ const _parent = shallowRef(parent ?? null);
22
+ watch(() => target, (v) => _target.value = v ?? null);
23
+ watch(() => parent, (v) => _parent.value = v ?? null);
24
+ const { size, position } = useFloatingIndicator({
25
+ target: _target,
26
+ parent: _parent,
27
+ orientation
28
+ });
29
+ const style = useVarsResolver(() => ({
30
+ root: {
31
+ "--fi-duration": duration === void 0 ? void 0 : duration === "number" ? `${duration}ms` : duration,
32
+ "--fi-size": `${size.value ?? 0}px`,
33
+ "--fi-position": `${position.value ?? 0}px`
34
+ }
35
+ }));
36
+ </script>
37
+
38
+ <template>
39
+ <Box
40
+ :is
41
+ v-if='target && parent && size !== null'
42
+ :style='style.root'
43
+ :class='$style.root'
44
+ :mod='[{ orientation }, mod]'
45
+ />
46
+ </template>
47
+
48
+ <style module>
49
+ .root{position:absolute;transition-duration:var(--fi-duration,.15s);transition-property:width,height,transform;transition-timing-function:ease;z-index:0}.root:where([data-orientation=horizontal]){bottom:0;left:0;top:0;transform:translateX(var(--fi-position));width:var(--fi-size)}.root:where([data-orientation=vertical]){height:var(--fi-size);left:0;right:0;top:0;transform:translateY(var(--fi-position))}
50
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { BoxProps } from './box.vue.js';
2
+ export interface FloatingIndicatorProps extends BoxProps {
3
+ /**
4
+ * Target element over which the indicator is displayed.
5
+ * The indicator will be positioned to match the target's size and position.
6
+ */
7
+ target: HTMLElement | null | undefined;
8
+ /**
9
+ * Parent container element that must have `position: relative`.
10
+ * The indicator's position is calculated relative to this element.
11
+ */
12
+ parent: HTMLElement | null | undefined;
13
+ /** Component orientation */
14
+ orientation?: 'horizontal' | 'vertical';
15
+ /** Transition duration in ms or CSS time value @default `150` */
16
+ transitionDuration?: number | string;
17
+ }
18
+ declare const __VLS_export: import("vue").DefineComponent<FloatingIndicatorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FloatingIndicatorProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
@@ -16,6 +16,7 @@ export type * from './date-time-picker.vue';
16
16
  export * from './dialog/index.js';
17
17
  export * from './drawer/index.js';
18
18
  export * from './files/index.js';
19
+ export type * from './floating-indicator.vue';
19
20
  export * from './input/index.js';
20
21
  export * from './link/index.js';
21
22
  export * from './loader/index.js';
@@ -25,6 +26,7 @@ export type * from './paper.vue';
25
26
  export * from './popover/index.js';
26
27
  export * from './progress/index.js';
27
28
  export * from './roving-focus/index.js';
29
+ export type * from './segmented-control.vue';
28
30
  export type * from './select.vue';
29
31
  export * from './switch/index.js';
30
32
  export * from './table/index.js';
@@ -1,5 +1,5 @@
1
1
  import type { NuxtLinkProps } from '#app';
2
2
  export declare function pickLinkProps<T extends NuxtLinkProps>(props: T): {
3
- link: Pick<T, "to" | "target" | "external" | "rel" | "noRel" | "prefetch" | "noPrefetch" | "replace" | "prefetchOn" | "trailingSlash" | "activeClass" | "ariaCurrentValue" | "exactActiveClass" | "prefetchedClass" | "viewTransition">;
4
- rest: Omit<T, "to" | "target" | "external" | "rel" | "noRel" | "prefetch" | "noPrefetch" | "replace" | "prefetchOn" | "trailingSlash" | "activeClass" | "ariaCurrentValue" | "exactActiveClass" | "prefetchedClass" | "viewTransition">;
3
+ link: Pick<T, "target" | "to" | "external" | "rel" | "noRel" | "prefetch" | "noPrefetch" | "replace" | "prefetchOn" | "trailingSlash" | "activeClass" | "ariaCurrentValue" | "exactActiveClass" | "prefetchedClass" | "viewTransition">;
4
+ rest: Omit<T, "target" | "to" | "external" | "rel" | "noRel" | "prefetch" | "noPrefetch" | "replace" | "prefetchOn" | "trailingSlash" | "activeClass" | "ariaCurrentValue" | "exactActiveClass" | "prefetchedClass" | "viewTransition">;
5
5
  };
@@ -69,7 +69,7 @@ const style = useVarsResolver((theme) => {
69
69
  :href
70
70
  :style='style.root'
71
71
  :class='$style.root'
72
- :mod='[{ active: active ?? isActive, disabled }, mod]'
72
+ :mod='[{ active: active || isActive, disabled }, mod]'
73
73
  :aria-current="isActive ? 'page' : void 0"
74
74
  :rel='"rel" in linkProps ? linkProps?.rel : void 0'
75
75
  :target='"target" in linkProps ? linkProps?.target : void 0'
@@ -22,5 +22,5 @@ const style = computed(() => ({
22
22
  </template>
23
23
 
24
24
  <style module>
25
- .root{--paper-radius:var(--radius-default);--paper-shadow:none;background-color:var(--color-body);border-radius:var(--paper-radius);box-shadow:var(--paper-shadow);display:block;outline:0;text-decoration:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.root:where([data-with-border]){border:rem(1px) solid var(--paper-border-color)}.root{@mixin light{--paper-border-color:var(--color-gray-3)}}.root{@mixin dark{--paper-border-color:var(--color-slate-7)}}
25
+ .root{--paper-radius:var(--radius-default);--paper-shadow:none;background-color:var(--color-body);border-radius:var(--paper-radius);box-shadow:var(--paper-shadow);display:block;outline:0;text-decoration:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.root:where([data-with-border]){border:rem(1px) solid var(--paper-border-color)}.root{@mixin light{--paper-border-color:var(--color-gray-3)}}.root{@mixin dark{--paper-border-color:var(--color-dark-7)}}
26
26
  </style>
@@ -20,7 +20,7 @@ export declare const useProvideRovingFocus: (args_0: State) => {
20
20
  attr: string;
21
21
  list: Readonly<ShallowRef<HTMLElement | null>>;
22
22
  loop: boolean | undefined;
23
- orientation: "both" | "horizontal" | "vertical" | undefined;
23
+ orientation: "horizontal" | "vertical" | "both" | undefined;
24
24
  init: () => number;
25
25
  focus: {
26
26
  (dir: "first" | "last"): void;
@@ -38,7 +38,7 @@ export declare const useRovingFocus: () => {
38
38
  attr: string;
39
39
  list: Readonly<ShallowRef<HTMLElement | null>>;
40
40
  loop: boolean | undefined;
41
- orientation: "both" | "horizontal" | "vertical" | undefined;
41
+ orientation: "horizontal" | "vertical" | "both" | undefined;
42
42
  init: () => number;
43
43
  focus: {
44
44
  (dir: "first" | "last"): void;
@@ -0,0 +1,46 @@
1
+ import type { AnyString, NuanceColor, NuanceRadius, NuanceSize } from '@nui/types';
2
+ import type { BoxProps } from './box.vue.js';
3
+ export interface SegmentedControlItem {
4
+ value: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface SegmentedControlProps extends BoxProps {
9
+ /** Items to render as controls */
10
+ data: (string | SegmentedControlItem)[];
11
+ /** Component size */
12
+ size?: NuanceSize | AnyString;
13
+ /** Border radius */
14
+ radius?: NuanceRadius;
15
+ /** Color from theme */
16
+ color?: NuanceColor;
17
+ /** Indicator `transition-duration` in ms */
18
+ transitionDuration?: number;
19
+ /** Indicator `transition-timing-function` */
20
+ transitionTimingFunction?: string;
21
+ /** Fills parent width */
22
+ fullWidth?: boolean;
23
+ /** Component orientation */
24
+ orientation?: 'horizontal' | 'vertical';
25
+ /** Disables the component */
26
+ disabled?: boolean;
27
+ /** Prevents value changes */
28
+ readOnly?: boolean;
29
+ /**
30
+ * Show borders between items
31
+ * @default `true`
32
+ */
33
+ withItemsBorders?: boolean;
34
+ }
35
+ type __VLS_Props = SegmentedControlProps;
36
+ type __VLS_ModelProps = {
37
+ modelValue?: string;
38
+ };
39
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
40
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
41
+ "update:modelValue": (value: string | undefined) => any;
42
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
43
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
44
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
45
+ declare const _default: typeof __VLS_export;
46
+ export default _default;
@@ -0,0 +1,130 @@
1
+ <script setup>
2
+ import { useVarsResolver } from "@nui/composables";
3
+ import { getFontSize, getRadius, getSize, getThemeColor } from "@nui/utils";
4
+ import { useTemplateRefsList } from "@vueuse/core";
5
+ import { computed, useId, useTemplateRef } from "vue";
6
+ import Box from "./box.vue";
7
+ import FloatingIndicator from "./floating-indicator.vue";
8
+ const {
9
+ is,
10
+ mod,
11
+ data,
12
+ size,
13
+ radius,
14
+ color,
15
+ transitionDuration,
16
+ transitionTimingFunction,
17
+ fullWidth,
18
+ orientation = "horizontal",
19
+ disabled,
20
+ readOnly,
21
+ withItemsBorders = true
22
+ } = defineProps({
23
+ data: { type: Array, required: true },
24
+ size: { type: [String, Object], required: false },
25
+ radius: { type: [String, Number], required: false },
26
+ color: { type: null, required: false },
27
+ transitionDuration: { type: Number, required: false },
28
+ transitionTimingFunction: { type: String, required: false },
29
+ fullWidth: { type: Boolean, required: false },
30
+ orientation: { type: String, required: false },
31
+ disabled: { type: Boolean, required: false },
32
+ readOnly: { type: Boolean, required: false },
33
+ withItemsBorders: { type: Boolean, required: false },
34
+ is: { type: null, required: false },
35
+ mod: { type: [Object, Array, null], required: false }
36
+ });
37
+ const value = defineModel({ type: String });
38
+ const items = computed(
39
+ () => data.map((item) => typeof item === "string" ? { value: item, label: item } : item)
40
+ );
41
+ if (value.value === void 0) {
42
+ const first = items.value.find((i) => !i.disabled);
43
+ if (first)
44
+ value.value = first.value;
45
+ }
46
+ const groupName = useId();
47
+ const rootRef = useTemplateRef("root");
48
+ const labelRefs = useTemplateRefsList();
49
+ const activeTarget = computed(() => {
50
+ if (value.value === void 0)
51
+ return null;
52
+ const index = items.value.findIndex((i) => i.value === value.value);
53
+ return index !== -1 ? labelRefs.value[index] ?? null : null;
54
+ });
55
+ const style = useVarsResolver((theme) => ({
56
+ root: {
57
+ "--sc-radius": getRadius(radius),
58
+ "--sc-color": color ? getThemeColor(color, theme) : void 0,
59
+ "--sc-shadow": color ? void 0 : "var(--shadow-xs)",
60
+ "--sc-transition-duration": transitionDuration === void 0 ? void 0 : `${transitionDuration}ms`,
61
+ "--sc-transition-timing-function": transitionTimingFunction,
62
+ "--sc-padding": getSize(size, "sc-padding"),
63
+ "--sc-font-size": getFontSize(size)
64
+ }
65
+ }));
66
+ </script>
67
+
68
+ <template>
69
+ <Box
70
+ :is
71
+ ref='root'
72
+ :style='style.root'
73
+ :class='$style.root'
74
+ :mod='[{
75
+ "full-width": fullWidth,
76
+ orientation,
77
+ disabled,
78
+ "with-items-borders": withItemsBorders
79
+ }, mod]'
80
+ role='radiogroup'
81
+ >
82
+ <FloatingIndicator
83
+ v-if='typeof value !== void 0'
84
+ :target='activeTarget'
85
+ :parent='rootRef'
86
+ :class='$style.indicator'
87
+ :orientation
88
+ />
89
+
90
+ <Box
91
+ v-for='item in items'
92
+ :key='item.value'
93
+ :class='$style.control'
94
+ :mod='{ active: value === item.value, orientation }'
95
+ >
96
+ <input
97
+ :id='`${groupName}-${item.value}`'
98
+ :key='`${item.value}-input`'
99
+ :class='$style.input'
100
+ type='radio'
101
+ :name='groupName'
102
+ :value='item.value'
103
+ :checked='value === item.value'
104
+ :disabled='disabled || item.disabled'
105
+ @change='!readOnly && (value = item.value)'
106
+ >
107
+
108
+ <Box
109
+ is='label'
110
+ :ref='labelRefs.set'
111
+ :for='`${groupName}-${item.value}`'
112
+ :class='$style.label'
113
+ :style='{
114
+ "--sc-label-color": !!color && "var(--color-white)"
115
+ }'
116
+ :mod='{
117
+ "active": value === item.value && !(disabled || item.disabled),
118
+ "disabled": disabled || item.disabled,
119
+ "read-only": readOnly
120
+ }'
121
+ >
122
+ <span :class='$style.innerLabel'>{{ item.label }}</span>
123
+ </Box>
124
+ </Box>
125
+ </Box>
126
+ </template>
127
+
128
+ <style module>
129
+ .root{--sc-padding-xs:2px 6px;--sc-padding-sm:3px 10px;--sc-padding-md:4px 14px;--sc-padding-lg:7px 16px;--sc-padding-xl:10px 20px;--sc-padding:var(--sc-padding-sm);--sc-radius:var(--radius-md);--sc-transition-duration:200ms;--sc-transition-timing-function:ease;--sc-font-size:var(--font-size-sm);border-radius:var(--sc-radius,var(--radius-md));display:inline-flex;flex-direction:row;overflow:hidden;padding:4px;position:relative;width:auto}.root:where([data-full-width]){display:flex}.root:where([data-orientation=vertical]){display:flex;flex-direction:column;width:-moz-max-content;width:max-content}.root:where([data-orientation=vertical]):where([data-full-width]){width:auto}.root{@mixin where-light{background-color:var(--color-gray-1)}}.root{@mixin where-dark{background-color:var(--color-dark-8)}}.indicator{border-radius:calc(var(--sc-radius, var(--radius-md)) + 2px);display:block;position:absolute;z-index:1}.indicator:where([data-orientation=horizontal]){bottom:4px;top:4px}.indicator:where([data-orientation=vertical]){left:4px;right:4px}.indicator{@mixin where-light{background-color:var(--sc-color,var(--color-white));box-shadow:var(--sc-shadow,none)}}.indicator{@mixin where-dark{background-color:var(--sc-color,var(--color-dark-5));box-shadow:none}}.label{border-radius:calc(var(--sc-radius, var(--radius-md)) + 2px);cursor:pointer;display:block;font-size:var(--sc-font-size);font-weight:500;outline:var(--segmented-control-outline,none);overflow:hidden;padding:var(--sc-padding);text-align:center;text-overflow:ellipsis;transition:color var(--sc-transition-duration) var(--sc-transition-timing-function);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap;-webkit-tap-highlight-color:transparent;@mixin where-light{color:var(--color-gray-7)}@mixin where-dark{color:var(--color-dark-1)}}.label:where([data-read-only]){cursor:default}.label:where([data-active]){@mixin where-light{color:var(--sc-label-color,var(--color-black))}@mixin where-dark{color:var(--sc-label-color,var(--color-white))}}.label:where([data-active]):before{border-radius:calc(var(--sc-radius, var(--radius-md)) + 2px);content:"";inset:0;position:absolute;z-index:0}.root:where([data-initialized]) .label:where([data-active]):before{display:none}.label:where([data-active]):before{@mixin where-light{box-shadow:var(--sc-shadow,none)}}.label:where([data-active]):before{@mixin where-dark{box-shadow:none}}.label:where([data-active])[data-disabled],fieldset:disabled .label:where([data-active]){color:var(--color-disabled-text);cursor:not-allowed}.label:where(:not([data-disabled],[data-active],[data-read-only])){@mixin hover{@mixin where-light{color:var(--color-black)}@mixin where-dark{color:var(--color-white)}}}fieldset:disabled .label{@mixin hover{color:var(--color-disabled-text)!important}}.input{height:0;opacity:0;overflow:hidden;position:absolute;white-space:nowrap;width:0}.input:focus-visible+.label{--segmented-control-outline:2px solid var(--color-primary-filled)}.control{flex:1;position:relative;transition:border-color var(--sc-transition-duration) var(--sc-transition-timing-function);z-index:2}.root[data-with-items-borders] :where(.control):before{background-color:var(--separator-color);bottom:0;content:"";inset-inline-start:0;position:absolute;top:0;transition:background-color var(--sc-transition-duration) var(--sc-transition-timing-function);width:1px}.control[data-orientation=vertical]:before{bottom:auto;height:1px;top:0;inset-inline:0;width:auto}.control:first-of-type:before,[data-mantine-color-scheme] .control[data-active]+.control:before,[data-mantine-color-scheme] .control[data-active]:before{--separator-color:transparent}.control{@mixin where-light{--separator-color:var(--color-gray-3)}}.control{@mixin where-dark{--separator-color:var(--color-dark-4)}}.innerLabel{position:relative;z-index:2}
130
+ </style>
@@ -0,0 +1,46 @@
1
+ import type { AnyString, NuanceColor, NuanceRadius, NuanceSize } from '@nui/types';
2
+ import type { BoxProps } from './box.vue.js';
3
+ export interface SegmentedControlItem {
4
+ value: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface SegmentedControlProps extends BoxProps {
9
+ /** Items to render as controls */
10
+ data: (string | SegmentedControlItem)[];
11
+ /** Component size */
12
+ size?: NuanceSize | AnyString;
13
+ /** Border radius */
14
+ radius?: NuanceRadius;
15
+ /** Color from theme */
16
+ color?: NuanceColor;
17
+ /** Indicator `transition-duration` in ms */
18
+ transitionDuration?: number;
19
+ /** Indicator `transition-timing-function` */
20
+ transitionTimingFunction?: string;
21
+ /** Fills parent width */
22
+ fullWidth?: boolean;
23
+ /** Component orientation */
24
+ orientation?: 'horizontal' | 'vertical';
25
+ /** Disables the component */
26
+ disabled?: boolean;
27
+ /** Prevents value changes */
28
+ readOnly?: boolean;
29
+ /**
30
+ * Show borders between items
31
+ * @default `true`
32
+ */
33
+ withItemsBorders?: boolean;
34
+ }
35
+ type __VLS_Props = SegmentedControlProps;
36
+ type __VLS_ModelProps = {
37
+ modelValue?: string;
38
+ };
39
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
40
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
41
+ "update:modelValue": (value: string | undefined) => any;
42
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
43
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
44
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
45
+ declare const _default: typeof __VLS_export;
46
+ export default _default;
@@ -39,9 +39,9 @@ type __VLS_Slots = {} & {
39
39
  description?: (props: typeof __VLS_32) => any;
40
40
  };
41
41
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
42
- "update:modelValue": (value: boolean) => any;
42
+ "update:modelValue": (value: boolean | undefined) => any;
43
43
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
44
- "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
44
+ "onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
45
45
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
46
46
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
47
47
  declare const _default: typeof __VLS_export;
@@ -46,7 +46,7 @@ const {
46
46
  const uuid = computed(() => id ?? useId());
47
47
  const ctx = useSwitchGroupState();
48
48
  const size = computed(() => _size ?? ctx?.size);
49
- const modelValue = defineModel({ type: Boolean, ...{ default: false } });
49
+ const modelValue = defineModel({ type: Boolean });
50
50
  const checked = computed({
51
51
  get: () => {
52
52
  if (ctx && value !== void 0)
@@ -134,5 +134,5 @@ const style = useVarsResolver((theme) => ({
134
134
  </template>
135
135
 
136
136
  <style module>
137
- .root{--switch-height-xs:rem(16px);--switch-height-sm:rem(20px);--switch-height-md:rem(24px);--switch-height-lg:rem(30px);--switch-height-xl:rem(36px);--switch-width-xs:rem(32px);--switch-width-sm:rem(38px);--switch-width-md:rem(46px);--switch-width-lg:rem(56px);--switch-width-xl:rem(72px);--switch-thumb-size-xs:rem(12px);--switch-thumb-size-sm:rem(14px);--switch-thumb-size-md:rem(18px);--switch-thumb-size-lg:rem(22px);--switch-thumb-size-xl:rem(28px);--switch-label-font-size-xs:rem(7px);--switch-label-font-size-sm:rem(9px);--switch-label-font-size-md:rem(10px);--switch-label-font-size-lg:rem(12px);--switch-label-font-size-xl:rem(16px);--switch-track-label-padding-xs:rem(3px);--switch-track-label-padding-sm:rem(3px);--switch-track-label-padding-md:rem(3.5px);--switch-track-label-padding-lg:rem(3.5px);--switch-track-label-padding-xl:rem(4px);--switch-height:var(--switch-height-sm);--switch-width:var(--switch-width-sm);--switch-thumb-size:var(--switch-thumb-size-sm);--switch-label-font-size:var(--switch-label-font-size-sm);--switch-track-label-padding:var(--switch-track-label-padding-sm);--switch-radius:1000px;--switch-color:var(--color-primary-filled);--switch-disabled-color:var(--color-disabled);position:relative}.input{height:100%;opacity:0;padding:0;position:absolute;white-space:nowrap;width:100%}.input,.track{margin:0;overflow:hidden}.track{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--switch-bg);border-radius:var(--switch-radius);color:var(--switch-text-color);cursor:var(--switch-cursor,pointer);display:flex;font-size:var(--switch-label-font-size);font-weight:var(--font-weight-medium);height:var(--switch-height);line-height:0;min-width:var(--switch-width);order:var(--switch-order,1);position:relative;transition:background-color .15s ease,border-color .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:0;-webkit-tap-highlight-color:transparent}.track:where([data-without-labels]){width:var(--switch-width)}.input:focus-visible+.track{outline:2px solid var(--color-primary-filled);outline-offset:2px}.input:checked+.track{--switch-bg:var(--switch-color);--switch-text-color:var(--color-white)}.input:disabled+.track,.input[data-disabled]+.track{--switch-bg:var(--switch-disabled-color);--switch-cursor:not-allowed}.track[data-label-position=left]{--switch-order:2}.track{@mixin where-light{--switch-bg:var(--color-gray-3);--switch-text-color:var(--color-gray-6)}}.track{@mixin where-dark{--switch-bg:var(--color-dark-5);--switch-text-color:var(--color-dark-1)}}.thumb{background-color:var(--switch-thumb-bg,var(--color-white));border-radius:var(--switch-radius);display:flex;height:var(--switch-thumb-size);inset-inline-start:var(--switch-thumb-start,var(--switch-track-label-padding));position:absolute;transition:inset-inline-start .15s ease;width:var(--switch-thumb-size);z-index:1}.thumb:where([data-with-indicator]):before{background-color:var(--switch-bg);border-radius:var(--switch-radius);content:"";height:40%;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:40%}.thumb>*{margin:auto}.input:checked+*>.thumb{--switch-thumb-start:calc(100% - var(--switch-thumb-size) - var(--switch-track-label-padding))}.input:disabled+*>.thumb,.input[data-disabled]+*>.thumb{--switch-thumb-bg:var(--switch-thumb-bg-disabled)}.thumb{@mixin where-light{--switch-thumb-bg-disabled:var(--color-gray-0)}}.thumb{@mixin where-dark{--switch-thumb-bg-disabled:var(--color-dark-3)}}.trackLabel{display:grid;height:100%;margin-inline-start:calc(var(--switch-thumb-size) + var(--switch-track-label-padding));min-width:calc(var(--switch-width) - var(--switch-thumb-size));padding-inline:var(--switch-track-label-padding);place-content:center;transition:margin .15s ease}.input:checked+*>.trackLabel{margin-inline-end:calc(var(--switch-thumb-size) + var(--switch-track-label-padding));margin-inline-start:0}
137
+ .root{--switch-height-xs:rem(16px);--switch-height-sm:rem(20px);--switch-height-md:rem(24px);--switch-height-lg:rem(30px);--switch-height-xl:rem(36px);--switch-width-xs:rem(32px);--switch-width-sm:rem(38px);--switch-width-md:rem(46px);--switch-width-lg:rem(56px);--switch-width-xl:rem(72px);--switch-thumb-size-xs:rem(12px);--switch-thumb-size-sm:rem(14px);--switch-thumb-size-md:rem(18px);--switch-thumb-size-lg:rem(22px);--switch-thumb-size-xl:rem(28px);--switch-label-font-size-xs:rem(7px);--switch-label-font-size-sm:rem(9px);--switch-label-font-size-md:rem(10px);--switch-label-font-size-lg:rem(12px);--switch-label-font-size-xl:rem(16px);--switch-track-label-padding-xs:rem(3px);--switch-track-label-padding-sm:rem(3px);--switch-track-label-padding-md:rem(3.5px);--switch-track-label-padding-lg:rem(3.5px);--switch-track-label-padding-xl:rem(4px);--switch-height:var(--switch-height-sm);--switch-width:var(--switch-width-sm);--switch-thumb-size:var(--switch-thumb-size-sm);--switch-label-font-size:var(--switch-label-font-size-sm);--switch-track-label-padding:var(--switch-track-label-padding-sm);--switch-radius:1000px;--switch-color:var(--color-primary-filled);--switch-disabled-color:var(--color-disabled);position:relative}.input{height:100%;opacity:0;padding:0;position:absolute;white-space:nowrap;width:100%}.input,.track{margin:0;overflow:hidden}.track{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--switch-bg);border-radius:var(--switch-radius);color:var(--switch-text-color);cursor:var(--switch-cursor,pointer);display:flex;font-size:var(--switch-label-font-size);font-weight:500;height:var(--switch-height);line-height:0;min-width:var(--switch-width);order:var(--switch-order,1);position:relative;transition:background-color .15s ease,border-color .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:0;-webkit-tap-highlight-color:transparent}.track:where([data-without-labels]){width:var(--switch-width)}.input:focus-visible+.track{outline:2px solid var(--color-primary-filled);outline-offset:2px}.input:checked+.track{--switch-bg:var(--switch-color);--switch-text-color:var(--color-white)}.input:disabled+.track,.input[data-disabled]+.track{--switch-bg:var(--switch-disabled-color);--switch-cursor:not-allowed}.track[data-label-position=left]{--switch-order:2}.track{@mixin where-light{--switch-bg:var(--color-gray-3);--switch-text-color:var(--color-gray-6)}}.track{@mixin where-dark{--switch-bg:var(--color-dark-5);--switch-text-color:var(--color-dark-1)}}.thumb{background-color:var(--switch-thumb-bg,var(--color-white));border-radius:var(--switch-radius);display:flex;height:var(--switch-thumb-size);inset-inline-start:var(--switch-thumb-start,var(--switch-track-label-padding));position:absolute;transition:inset-inline-start .15s ease;width:var(--switch-thumb-size);z-index:1}.thumb:where([data-with-indicator]):before{background-color:var(--switch-bg);border-radius:var(--switch-radius);content:"";height:40%;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:40%}.thumb>*{margin:auto}.input:checked+*>.thumb{--switch-thumb-start:calc(100% - var(--switch-thumb-size) - var(--switch-track-label-padding))}.input:disabled+*>.thumb,.input[data-disabled]+*>.thumb{--switch-thumb-bg:var(--switch-thumb-bg-disabled)}.thumb{@mixin where-light{--switch-thumb-bg-disabled:var(--color-gray-0)}}.thumb{@mixin where-dark{--switch-thumb-bg-disabled:var(--color-dark-3)}}.trackLabel{display:grid;height:100%;margin-inline-start:calc(var(--switch-thumb-size) + var(--switch-track-label-padding));min-width:calc(var(--switch-width) - var(--switch-thumb-size));padding-inline:var(--switch-track-label-padding);place-content:center;transition:margin .15s ease}.input:checked+*>.trackLabel{margin-inline-end:calc(var(--switch-thumb-size) + var(--switch-track-label-padding));margin-inline-start:0}
138
138
  </style>