@leavepulse/ui 0.37.10 → 0.37.11

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.
@@ -0,0 +1,94 @@
1
+ import { defineComponent, useSlots, computed, openBlock, createElementBlock, mergeProps, unref, renderSlot, createTextVNode, toDisplayString, createCommentVNode, createVNode, normalizeClass, withCtx, createBlock } from "vue";
2
+ import { SwitchRoot, SwitchThumb } from "reka-ui";
3
+ import { useMergedAttrs } from "../composables/useMergedClass.js";
4
+ const _hoisted_1 = {
5
+ key: 0,
6
+ class: "flex min-w-0 flex-col"
7
+ };
8
+ const _hoisted_2 = {
9
+ key: 0,
10
+ class: "text-xs text-muted"
11
+ };
12
+ const _hoisted_3 = {
13
+ key: 1,
14
+ class: "flex min-w-0 flex-col"
15
+ };
16
+ const _hoisted_4 = {
17
+ key: 0,
18
+ class: "text-xs text-muted"
19
+ };
20
+ const __default__ = { inheritAttrs: false };
21
+ const _sfc_main = /* @__PURE__ */ defineComponent({
22
+ ...__default__,
23
+ __name: "LpSwitch",
24
+ props: {
25
+ modelValue: { type: Boolean },
26
+ disabled: { type: Boolean },
27
+ label: {},
28
+ description: {},
29
+ labelPosition: { default: "end" }
30
+ },
31
+ emits: ["update:modelValue"],
32
+ setup(__props, { emit: __emit }) {
33
+ const props = __props;
34
+ const emit = __emit;
35
+ const slots = useSlots();
36
+ const labelled = computed(() => Boolean(props.label || props.description || slots.default));
37
+ const TRACK = "group inline-flex h-5 w-9 shrink-0 items-center rounded-pill border border-line bg-surface-soft px-0.5 outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=checked]:border-transparent data-[state=checked]:bg-brand disabled:cursor-not-allowed disabled:opacity-55";
38
+ const THUMB = "h-3.5 w-3.5 rounded-full bg-ink shadow transition-[translate,width,background-color] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-active:w-5 group-data-[state=checked]:translate-x-4 group-data-[state=checked]:bg-ink-inverse group-data-[state=checked]:group-active:-translate-x-1 motion-reduce:group-active:w-3.5";
39
+ const { class: rootClass, attrs: rest } = useMergedAttrs(() => {
40
+ if (!labelled.value) return TRACK;
41
+ return props.labelPosition === "start" ? "flex w-full cursor-pointer items-center justify-between gap-3 text-sm text-ink" : "inline-flex cursor-pointer items-center gap-2 text-sm text-ink";
42
+ });
43
+ function onUpdate(value) {
44
+ emit("update:modelValue", value);
45
+ }
46
+ return (_ctx, _cache) => {
47
+ return labelled.value ? (openBlock(), createElementBlock("label", mergeProps({
48
+ key: 0,
49
+ class: [unref(rootClass), __props.disabled && "cursor-not-allowed"]
50
+ }, unref(rest)), [
51
+ __props.labelPosition === "start" ? (openBlock(), createElementBlock("span", _hoisted_1, [
52
+ renderSlot(_ctx.$slots, "default", {}, () => [
53
+ createTextVNode(toDisplayString(__props.label), 1)
54
+ ]),
55
+ __props.description ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.description), 1)) : createCommentVNode("", true)
56
+ ])) : createCommentVNode("", true),
57
+ createVNode(unref(SwitchRoot), {
58
+ "model-value": __props.modelValue,
59
+ disabled: __props.disabled,
60
+ class: normalizeClass(TRACK),
61
+ "onUpdate:modelValue": onUpdate
62
+ }, {
63
+ default: withCtx(() => [
64
+ createVNode(unref(SwitchThumb), {
65
+ class: normalizeClass(THUMB)
66
+ })
67
+ ]),
68
+ _: 1
69
+ }, 8, ["model-value", "disabled"]),
70
+ __props.labelPosition === "end" ? (openBlock(), createElementBlock("span", _hoisted_3, [
71
+ renderSlot(_ctx.$slots, "default", {}, () => [
72
+ createTextVNode(toDisplayString(__props.label), 1)
73
+ ]),
74
+ __props.description ? (openBlock(), createElementBlock("span", _hoisted_4, toDisplayString(__props.description), 1)) : createCommentVNode("", true)
75
+ ])) : createCommentVNode("", true)
76
+ ], 16)) : (openBlock(), createBlock(unref(SwitchRoot), mergeProps({
77
+ key: 1,
78
+ "model-value": __props.modelValue,
79
+ disabled: __props.disabled,
80
+ class: unref(rootClass)
81
+ }, unref(rest), { "onUpdate:modelValue": onUpdate }), {
82
+ default: withCtx(() => [
83
+ createVNode(unref(SwitchThumb), {
84
+ class: normalizeClass(THUMB)
85
+ })
86
+ ]),
87
+ _: 1
88
+ }, 16, ["model-value", "disabled", "class"]));
89
+ };
90
+ }
91
+ });
92
+ export {
93
+ _sfc_main as _
94
+ };
@@ -1,13 +1,42 @@
1
1
  declare const _default: typeof __VLS_export;
2
2
  export default _default;
3
- declare const __VLS_export: import('vue').DefineComponent<{
3
+ declare const __VLS_export: __VLS_WithSlots<import('vue').DefineComponent<{
4
4
  modelValue?: boolean;
5
5
  disabled?: boolean;
6
+ label?: string;
7
+ /** Secondary line under the label. */
8
+ description?: string;
9
+ /**
10
+ * Where the text sits. `end` (default) reads like LpCheckbox: switch, then
11
+ * text. `start` is the settings-row shape: text on the left, the switch
12
+ * pushed to the right edge of the row.
13
+ */
14
+ labelPosition?: "start" | "end";
6
15
  }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
7
16
  "update:modelValue": (value: boolean) => any;
8
17
  }, string, import('vue').PublicProps, Readonly<{
9
18
  modelValue?: boolean;
10
19
  disabled?: boolean;
20
+ label?: string;
21
+ /** Secondary line under the label. */
22
+ description?: string;
23
+ /**
24
+ * Where the text sits. `end` (default) reads like LpCheckbox: switch, then
25
+ * text. `start` is the settings-row shape: text on the left, the switch
26
+ * pushed to the right edge of the row.
27
+ */
28
+ labelPosition?: "start" | "end";
11
29
  }> & Readonly<{
12
30
  "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
13
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
31
+ }>, {
32
+ labelPosition: "start" | "end";
33
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>, {
34
+ default?: (props: {}) => any;
35
+ } & {
36
+ default?: (props: {}) => any;
37
+ }>;
38
+ type __VLS_WithSlots<T, S> = T & {
39
+ new (): {
40
+ $slots: S;
41
+ };
42
+ };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSwitch-xgnRU2k0.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSwitch-Blizvqyt.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
package/dist/index.js CHANGED
@@ -70,7 +70,7 @@ import { _ as _58 } from "./chunks/LpSlider-BwNIBkAK.js";
70
70
  import { _ as _59 } from "./chunks/LpSparkline-C6xQ2dwv.js";
71
71
  import { _ as _60 } from "./chunks/LpStat-CQaW8R--.js";
72
72
  import { _ as _61 } from "./chunks/LpStepper-Bk-XaQYU.js";
73
- import { _ as _62 } from "./chunks/LpSwitch-xgnRU2k0.js";
73
+ import { _ as _62 } from "./chunks/LpSwitch-Blizvqyt.js";
74
74
  import { default as default7 } from "./components/LpTable.vue.js";
75
75
  import { _ as _63 } from "./chunks/LpTableOfContents-CjvxPMpU.js";
76
76
  import { _ as _64 } from "./chunks/LpTabs-Cefe_lys.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.37.10",
3
+ "version": "0.37.11",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -6,28 +6,73 @@ export default { inheritAttrs: false }
6
6
  </script>
7
7
 
8
8
  <script setup lang="ts">
9
+ import { computed, useSlots } from "vue"
9
10
  import { SwitchRoot, SwitchThumb } from "reka-ui"
10
11
  import { useMergedAttrs } from "../composables/useMergedClass"
11
12
 
12
- defineProps<{ modelValue?: boolean; disabled?: boolean }>()
13
- defineEmits<{ (e: "update:modelValue", value: boolean): void }>()
14
-
15
- // A switch has a fixed track size, so a consumer asking for a bigger one must not have to depend on stylesheet order to get it.
16
- const { class: rootClass, attrs: rest } = useMergedAttrs(
17
- "group inline-flex h-5 w-9 shrink-0 items-center rounded-pill border border-line bg-surface-soft px-0.5 outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=checked]:border-transparent data-[state=checked]:bg-brand disabled:cursor-not-allowed disabled:opacity-55",
13
+ const props = withDefaults(
14
+ defineProps<{
15
+ modelValue?: boolean
16
+ disabled?: boolean
17
+ label?: string
18
+ /** Secondary line under the label. */
19
+ description?: string
20
+ /**
21
+ * Where the text sits. `end` (default) reads like LpCheckbox: switch, then
22
+ * text. `start` is the settings-row shape: text on the left, the switch
23
+ * pushed to the right edge of the row.
24
+ */
25
+ labelPosition?: "start" | "end"
26
+ }>(),
27
+ { labelPosition: "end" },
18
28
  )
29
+ const emit = defineEmits<{ (e: "update:modelValue", value: boolean): void }>()
30
+
31
+ const slots = useSlots()
32
+ const labelled = computed(() => Boolean(props.label || props.description || slots.default))
33
+
34
+ const TRACK =
35
+ "group inline-flex h-5 w-9 shrink-0 items-center rounded-pill border border-line bg-surface-soft px-0.5 outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=checked]:border-transparent data-[state=checked]:bg-brand disabled:cursor-not-allowed disabled:opacity-55"
36
+ const THUMB =
37
+ "h-3.5 w-3.5 rounded-full bg-ink shadow transition-[translate,width,background-color] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-active:w-5 group-data-[state=checked]:translate-x-4 group-data-[state=checked]:bg-ink-inverse group-data-[state=checked]:group-active:-translate-x-1 motion-reduce:group-active:w-3.5"
38
+
39
+ // Bare, the switch is the root, so a consumer asking for a bigger track must not
40
+ // have to depend on stylesheet order to get it. With text, the row is the root
41
+ // and the consumer's class lays out the row, as on LpCheckbox.
42
+ const { class: rootClass, attrs: rest } = useMergedAttrs(() => {
43
+ if (!labelled.value) return TRACK
44
+ return props.labelPosition === "start"
45
+ ? "flex w-full cursor-pointer items-center justify-between gap-3 text-sm text-ink"
46
+ : "inline-flex cursor-pointer items-center gap-2 text-sm text-ink"
47
+ })
48
+
49
+ function onUpdate(value: boolean) {
50
+ emit("update:modelValue", value)
51
+ }
19
52
  </script>
20
53
 
21
54
  <template>
55
+ <label v-if="labelled" :class="[rootClass, disabled && 'cursor-not-allowed']" v-bind="rest">
56
+ <span v-if="labelPosition === 'start'" class="flex min-w-0 flex-col">
57
+ <slot>{{ label }}</slot>
58
+ <span v-if="description" class="text-xs text-muted">{{ description }}</span>
59
+ </span>
60
+ <SwitchRoot :model-value="modelValue" :disabled="disabled" :class="TRACK" @update:model-value="onUpdate">
61
+ <SwitchThumb :class="THUMB" />
62
+ </SwitchRoot>
63
+ <span v-if="labelPosition === 'end'" class="flex min-w-0 flex-col">
64
+ <slot>{{ label }}</slot>
65
+ <span v-if="description" class="text-xs text-muted">{{ description }}</span>
66
+ </span>
67
+ </label>
22
68
  <SwitchRoot
69
+ v-else
23
70
  :model-value="modelValue"
24
71
  :disabled="disabled"
25
72
  :class="rootClass"
26
73
  v-bind="rest"
27
- @update:model-value="(v) => $emit('update:modelValue', v)"
74
+ @update:model-value="onUpdate"
28
75
  >
29
- <SwitchThumb
30
- class="h-3.5 w-3.5 rounded-full bg-ink shadow transition-[translate,width,background-color] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-active:w-5 group-data-[state=checked]:translate-x-4 group-data-[state=checked]:bg-ink-inverse group-data-[state=checked]:group-active:-translate-x-1 motion-reduce:group-active:w-3.5"
31
- />
76
+ <SwitchThumb :class="THUMB" />
32
77
  </SwitchRoot>
33
78
  </template>
@@ -1,35 +0,0 @@
1
- import { defineComponent, openBlock, createBlock, unref, mergeProps, withCtx, createVNode } from "vue";
2
- import { SwitchRoot, SwitchThumb } from "reka-ui";
3
- import { useMergedAttrs } from "../composables/useMergedClass.js";
4
- const __default__ = { inheritAttrs: false };
5
- const _sfc_main = /* @__PURE__ */ defineComponent({
6
- ...__default__,
7
- __name: "LpSwitch",
8
- props: {
9
- modelValue: { type: Boolean },
10
- disabled: { type: Boolean }
11
- },
12
- emits: ["update:modelValue"],
13
- setup(__props) {
14
- const { class: rootClass, attrs: rest } = useMergedAttrs(
15
- "group inline-flex h-5 w-9 shrink-0 items-center rounded-pill border border-line bg-surface-soft px-0.5 outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=checked]:border-transparent data-[state=checked]:bg-brand disabled:cursor-not-allowed disabled:opacity-55"
16
- );
17
- return (_ctx, _cache) => {
18
- return openBlock(), createBlock(unref(SwitchRoot), mergeProps({
19
- "model-value": __props.modelValue,
20
- disabled: __props.disabled,
21
- class: unref(rootClass)
22
- }, unref(rest), {
23
- "onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => _ctx.$emit("update:modelValue", v))
24
- }), {
25
- default: withCtx(() => [
26
- createVNode(unref(SwitchThumb), { class: "h-3.5 w-3.5 rounded-full bg-ink shadow transition-[translate,width,background-color] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-active:w-5 group-data-[state=checked]:translate-x-4 group-data-[state=checked]:bg-ink-inverse group-data-[state=checked]:group-active:-translate-x-1 motion-reduce:group-active:w-3.5" })
27
- ]),
28
- _: 1
29
- }, 16, ["model-value", "disabled", "class"]);
30
- };
31
- }
32
- });
33
- export {
34
- _sfc_main as _
35
- };