@threadlabs/looma 0.14.0 → 0.14.2

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,194 @@
1
+ <!-- Generated by HTML Next 1.0.0-alpha.7 for Vue 3.5. Do not edit. -->
2
+ <script setup lang="ts">
3
+ import { computed } from 'vue'
4
+
5
+ defineOptions({ inheritAttrs: false })
6
+
7
+ const props = withDefaults(
8
+ defineProps<{
9
+ label?: string
10
+ max?: number
11
+ size?: 'sm' | 'md'
12
+ tone?: 'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'
13
+ value?: number
14
+ valueText?: string
15
+ }>(),
16
+ {
17
+ label: '',
18
+ max: 1,
19
+ size: 'md',
20
+ tone: 'neutral',
21
+ value: 0,
22
+ valueText: '',
23
+ },
24
+ )
25
+
26
+ const amount = computed(() => Math.min(Math.max(0, props.value), props.max))
27
+ const percent = computed(() =>
28
+ ({
29
+ true: number(
30
+ number(amount.value) === undefined || number(props.max) === undefined
31
+ ? undefined
32
+ : number(amount.value)! / number(props.max)!,
33
+ ) === undefined || number(100) === undefined
34
+ ? undefined
35
+ : number(
36
+ number(amount.value) === undefined || number(props.max) === undefined
37
+ ? undefined
38
+ : number(amount.value)! / number(props.max)!,
39
+ )! * number(100)!,
40
+ false: 0,
41
+ })[`${props.max > 0}`]
42
+ )
43
+ const whole = computed(
44
+ () => (number(
45
+ number(percent.value) === undefined || number(0.5) === undefined
46
+ ? undefined
47
+ : number(percent.value)! + number(0.5)!,
48
+ ) === undefined
49
+ || number(
50
+ number(
51
+ number(percent.value) === undefined || number(0.5) === undefined
52
+ ? undefined
53
+ : number(percent.value)! + number(0.5)!,
54
+ ) === undefined || number(1) === undefined
55
+ ? undefined
56
+ : number(
57
+ number(percent.value) === undefined || number(0.5) === undefined
58
+ ? undefined
59
+ : number(percent.value)! + number(0.5)!,
60
+ )! % number(1)!,
61
+ ) === undefined
62
+ ? undefined
63
+ : number(
64
+ number(percent.value) === undefined || number(0.5) === undefined
65
+ ? undefined
66
+ : number(percent.value)! + number(0.5)!,
67
+ )! - number(
68
+ number(
69
+ number(percent.value) === undefined || number(0.5) === undefined
70
+ ? undefined
71
+ : number(percent.value)! + number(0.5)!,
72
+ ) === undefined || number(1) === undefined
73
+ ? undefined
74
+ : number(
75
+ number(percent.value) === undefined || number(0.5) === undefined
76
+ ? undefined
77
+ : number(percent.value)! + number(0.5)!,
78
+ )! % number(1)!,
79
+ )!)
80
+ )
81
+
82
+ /** The values the styles' :host-state() rules test. */
83
+ const hostState = computed(() =>
84
+ [
85
+ props.size && `size size=${props.size}`,
86
+ props.tone && `tone tone=${props.tone}`,
87
+ ].filter(Boolean).join(' ')
88
+ )
89
+
90
+ function text(value: unknown): string {
91
+ if (Array.isArray(value)) return value.map(text).join(' ')
92
+ return value === null || value === undefined || typeof value === 'object' ? '' : String(value)
93
+ }
94
+
95
+ function attribute(value: unknown): any {
96
+ if (
97
+ value === null || value === undefined || value === false
98
+ || (typeof value === 'object' && !Array.isArray(value))
99
+ ) return undefined
100
+ return value === true ? '' : text(value)
101
+ }
102
+
103
+ function number(value: unknown): number | undefined {
104
+ return typeof value === 'number' && !Number.isNaN(value) ? value : undefined
105
+ }
106
+ </script>
107
+
108
+ <template>
109
+ <span
110
+ data-component="ui-meter"
111
+ role="meter"
112
+ aria-valuemin="0"
113
+ v-bind="$attrs"
114
+ :aria-valuemax="max"
115
+ :aria-valuenow="amount"
116
+ :aria-valuetext="typeof (({ true: valueText, false: `${whole ?? ''}%` })[`${valueText !== ''}`]) === 'boolean'
117
+ ? String(({ true: valueText, false: `${whole ?? ''}%` })[`${valueText !== ''}`])
118
+ : attribute(({ true: valueText, false: `${whole ?? ''}%` })[`${valueText !== ''}`])"
119
+ :aria-label="typeof (({ true: label, false: null })[`${label !== ''}`]) === 'boolean'
120
+ ? String(({ true: label, false: null })[`${label !== ''}`])
121
+ : attribute(({ true: label, false: null })[`${label !== ''}`])"
122
+ :data-ui-meter-state="hostState || undefined"
123
+ ><span class="fill" :style="{ 'inline-size': `${text(percent)}%` }"></span></span>
124
+ </template>
125
+
126
+ <style scoped>
127
+ /* How far along something is: a track, filled from the start in the tone's colour. The track is a
128
+ quiet border colour, so an empty meter still shows; every tone's fill keeps 3:1 against the
129
+ track and the page. */
130
+ @property --ui-meter-inline-size {
131
+ syntax: "*";
132
+ inherits: false;
133
+ }
134
+
135
+ [data-component~="ui-meter"] {
136
+ --_meter-fill: var(--ui-text-muted);
137
+
138
+ display: inline-block;
139
+ flex: none;
140
+ vertical-align: middle;
141
+ inline-size: var(--ui-meter-inline-size, 8rem);
142
+ max-inline-size: 100%;
143
+ block-size: var(--ui-space-2);
144
+ overflow: hidden;
145
+ border-radius: var(--ui-radius-round);
146
+ background: var(--ui-border);
147
+ /* Unseen until forced colours draw it, where the track's own colour is gone. */
148
+ outline: 1px solid transparent;
149
+ }
150
+
151
+ [data-component~="ui-meter"][data-ui-meter-state~="size=sm"] {
152
+ inline-size: var(--ui-meter-inline-size, 5rem);
153
+ block-size: var(--ui-space-1);
154
+ }
155
+
156
+ .fill {
157
+ display: block;
158
+ block-size: 100%;
159
+ background: var(--_meter-fill);
160
+ }
161
+
162
+ [data-component~="ui-meter"][data-ui-meter-state~="tone=accent"] {
163
+ --_meter-fill: var(--ui-accent-solid);
164
+ }
165
+
166
+ [data-component~="ui-meter"][data-ui-meter-state~="tone=info"] {
167
+ --_meter-fill: var(--ui-info-solid);
168
+ }
169
+
170
+ [data-component~="ui-meter"][data-ui-meter-state~="tone=success"] {
171
+ --_meter-fill: var(--ui-success-solid);
172
+ }
173
+
174
+ [data-component~="ui-meter"][data-ui-meter-state~="tone=warning"] {
175
+ --_meter-fill: var(--ui-warning-solid);
176
+ }
177
+
178
+ [data-component~="ui-meter"][data-ui-meter-state~="tone=danger"] {
179
+ --_meter-fill: var(--ui-danger-solid);
180
+ }
181
+
182
+ /* Forced colours drop backgrounds: draw the fill in the text colour inside the outlined track. */
183
+ @media (forced-colors: active) {
184
+ .fill {
185
+ forced-color-adjust: none;
186
+ background: CanvasText;
187
+ }
188
+ }
189
+
190
+ /* A component that sets its display still honours the hidden attribute on its root. */
191
+ [data-component~="ui-meter"][hidden] {
192
+ display: none;
193
+ }
194
+ </style>
@@ -0,0 +1,20 @@
1
+ type __VLS_Props = {
2
+ density?: 'comfortable' | 'compact';
3
+ stickyHeader?: boolean;
4
+ };
5
+ declare var __VLS_1: {};
6
+ type __VLS_Slots = {} & {
7
+ default?: (props: typeof __VLS_1) => any;
8
+ };
9
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ density: "comfortable" | "compact";
11
+ stickyHeader: boolean;
12
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
package/vue/UiTable.js ADDED
@@ -0,0 +1,2 @@
1
+ import { t as UiTable_default } from "./chunks/UiTable.js";
2
+ export { UiTable_default as default };
@@ -0,0 +1,172 @@
1
+ <!-- Generated by HTML Next 1.0.0-alpha.7 for Vue 3.5. Do not edit. -->
2
+ <script setup lang="ts">
3
+ import { computed, ref } from 'vue'
4
+ import * as controllerModule from '../components/ui-table/ui-table.js'
5
+ import { createDispatch, useComponentHost } from './host'
6
+
7
+ defineOptions({ inheritAttrs: false })
8
+
9
+ const props = withDefaults(
10
+ defineProps<{
11
+ density?: 'comfortable' | 'compact'
12
+ stickyHeader?: boolean
13
+ }>(),
14
+ {
15
+ density: 'comfortable',
16
+ stickyHeader: false,
17
+ },
18
+ )
19
+
20
+ const root = ref<HTMLElement | null>(null)
21
+
22
+ /** The values the styles' :host-state() rules test. */
23
+ const hostState = computed(() =>
24
+ [
25
+ props.density && `density density=${props.density}`,
26
+ props.stickyHeader && 'stickyHeader',
27
+ ].filter(Boolean).join(' ')
28
+ )
29
+
30
+ const dispatch = createDispatch(root)
31
+
32
+ useComponentHost(controllerModule.default, {
33
+ root,
34
+ dispatch,
35
+ props,
36
+ })
37
+ </script>
38
+
39
+ <template>
40
+ <div
41
+ data-component="ui-table"
42
+ v-bind="$attrs"
43
+ :data-ui-table-state="hostState || undefined"
44
+ ref="root"
45
+ >
46
+ <slot />
47
+ </div>
48
+ </template>
49
+
50
+ <style scoped>
51
+ /* Styles an authored <table> (caption, thead, tbody, th scope) without replacing it: the table is
52
+ meaningful before JavaScript, and a screen reader reads it as a table. The root scrolls a table
53
+ wider than it, or taller than a bounded height; while it does, the controller makes the root a named, focusable region so a
54
+ keyboard can scroll it. A cell's data-ui-align (start, center, or end; start by default) sets its
55
+ content along the row, such as end for a column of figures. */
56
+ [data-component~="ui-table"] {
57
+ --_pad-block: var(--ui-space-1);
58
+ --_pad-inline: var(--ui-space-3);
59
+ --_row-size: var(--ui-control-size);
60
+ display: block;
61
+ box-sizing: border-box;
62
+ max-inline-size: 100%;
63
+ min-inline-size: 0;
64
+ min-block-size: 0;
65
+ overflow: auto;
66
+ overscroll-behavior-inline: contain;
67
+ /* The sideways scroll fade every Looma scroller uses (see ui-scroll-area). Only the inline edges
68
+ fade, so a sticky header never fades. */
69
+ --_ui-scroll-fade-direction: to right;
70
+ --_ui-scroll-fade-size: var(--ui-scroll-fade-size, 24px);
71
+ mask-image: linear-gradient(
72
+ var(--_ui-scroll-fade-direction),
73
+ transparent,
74
+ #000 var(--_ui-scroll-fade-start),
75
+ #000 calc(100% - var(--_ui-scroll-fade-end)),
76
+ transparent
77
+ );
78
+ animation:
79
+ ui-scroll-fade-start linear,
80
+ ui-scroll-fade-start-hold linear,
81
+ ui-scroll-fade-end-hold linear,
82
+ ui-scroll-fade-end linear;
83
+ animation-timeline: scroll(self inline);
84
+ animation-range:
85
+ 0 var(--_ui-scroll-fade-size),
86
+ var(--_ui-scroll-fade-size) calc(100% + 1px),
87
+ -1px calc(100% - var(--_ui-scroll-fade-size)),
88
+ calc(100% - var(--_ui-scroll-fade-size)) 100%;
89
+ }
90
+
91
+ [data-component~="ui-table"]:dir(rtl) {
92
+ --_ui-scroll-fade-direction: to left;
93
+ }
94
+
95
+ [data-component~="ui-table"]:focus-visible {
96
+ outline: 2px solid var(--ui-focus-ring);
97
+ outline-offset: -2px;
98
+ }
99
+
100
+ [data-component~="ui-table"][data-ui-table-state~="density=compact"] {
101
+ --_pad-block: var(--ui-space-0-5);
102
+ --_pad-inline: var(--ui-space-2);
103
+ --_row-size: var(--ui-control-size-sm);
104
+ }
105
+
106
+ /* Separate borders stay on their cells when a sticky header scrolls; collapsed ones stay behind. */
107
+ :slotted(table) {
108
+ inline-size: 100%;
109
+ border-collapse: separate;
110
+ border-spacing: 0;
111
+ color: var(--ui-text-primary);
112
+ font-size: var(--ui-font-size-sm);
113
+ line-height: var(--ui-line-height);
114
+ font-variant-numeric: tabular-nums;
115
+ }
116
+
117
+ :slotted(caption) {
118
+ padding-block-end: var(--ui-space-2);
119
+ color: var(--ui-text-secondary);
120
+ font-weight: var(--ui-font-medium);
121
+ text-align: start;
122
+ }
123
+
124
+ /* Every row is at least one control tall, so a row holding a checkbox, select, or input keeps the
125
+ rhythm of the rows around it. A cell's height is its minimum. */
126
+ :slotted(th),
127
+ :slotted(td) {
128
+ block-size: var(--_row-size);
129
+ padding: var(--_pad-block) var(--_pad-inline);
130
+ border-block-end: 1px solid var(--ui-border-subtle);
131
+ text-align: start;
132
+ vertical-align: middle;
133
+ }
134
+
135
+ :slotted(thead th) {
136
+ block-size: auto;
137
+ padding-block: var(--ui-space-2);
138
+ border-block-end-color: var(--ui-border-default);
139
+ background: var(--ui-surface);
140
+ color: var(--ui-text-muted);
141
+ font-weight: var(--ui-font-medium);
142
+ white-space: nowrap;
143
+ vertical-align: bottom;
144
+ }
145
+
146
+ :slotted(tbody th) {
147
+ font-weight: var(--ui-font-medium);
148
+ }
149
+
150
+ :slotted(tbody tr:last-child > *) {
151
+ border-block-end-width: 0;
152
+ }
153
+
154
+ :slotted([data-ui-align="center"]) {
155
+ text-align: center;
156
+ }
157
+
158
+ :slotted([data-ui-align="end"]) {
159
+ text-align: end;
160
+ }
161
+
162
+ [data-component~="ui-table"][data-ui-table-state~="stickyHeader"] :slotted(thead th) {
163
+ position: sticky;
164
+ inset-block-start: 0;
165
+ z-index: 1;
166
+ }
167
+
168
+ /* A component that sets its display still honours the hidden attribute on its root. */
169
+ [data-component~="ui-table"][hidden] {
170
+ display: none;
171
+ }
172
+ </style>
@@ -7,15 +7,23 @@ var _hoisted_1 = ["data-ui-description-list-state"];
7
7
  var UiDescriptionList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
8
8
  inheritAttrs: false,
9
9
  __name: "UiDescriptionList",
10
- props: { layout: { default: "rows" } },
10
+ props: {
11
+ columns: {},
12
+ density: { default: "comfortable" },
13
+ layout: { default: "rows" }
14
+ },
11
15
  setup(__props) {
12
16
  const props = __props;
13
17
  /** The values the styles' :host-state() rules test. */
14
- const hostState = computed(() => [props.layout && `layout layout=${props.layout}`].filter(Boolean).join(" "));
18
+ const hostState = computed(() => [
19
+ props.layout && `layout layout=${props.layout}`,
20
+ props.columns && `columns columns=${props.columns}`,
21
+ props.density && `density density=${props.density}`
22
+ ].filter(Boolean).join(" "));
15
23
  return (_ctx, _cache) => {
16
24
  return openBlock(), createElementBlock("dl", mergeProps({ "data-component": "ui-description-list" }, _ctx.$attrs, { "data-ui-description-list-state": hostState.value || void 0 }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1);
17
25
  };
18
26
  }
19
- }), [["__scopeId", "data-v-a4548235"]]);
27
+ }), [["__scopeId", "data-v-640c2332"]]);
20
28
  //#endregion
21
29
  export { UiDescriptionList_default as t };
@@ -0,0 +1,82 @@
1
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
2
+ import { computed, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeStyle, openBlock } from "vue";
3
+ //#region .build/vue/UiMeter.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = [
5
+ "aria-valuemax",
6
+ "aria-valuenow",
7
+ "aria-valuetext",
8
+ "aria-label",
9
+ "data-ui-meter-state"
10
+ ];
11
+ //#endregion
12
+ //#region .build/vue/UiMeter.vue
13
+ var UiMeter_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
14
+ inheritAttrs: false,
15
+ __name: "UiMeter",
16
+ props: {
17
+ label: { default: "" },
18
+ max: { default: 1 },
19
+ size: { default: "md" },
20
+ tone: { default: "neutral" },
21
+ value: { default: 0 },
22
+ valueText: { default: "" }
23
+ },
24
+ setup(__props) {
25
+ const props = __props;
26
+ const amount = computed(() => Math.min(Math.max(0, props.value), props.max));
27
+ const percent = computed(() => ({
28
+ true: number(number(amount.value) === void 0 || number(props.max) === void 0 ? void 0 : number(amount.value) / number(props.max)) === void 0 || number(100) === void 0 ? void 0 : number(number(amount.value) === void 0 || number(props.max) === void 0 ? void 0 : number(amount.value) / number(props.max)) * number(100),
29
+ false: 0
30
+ })[`${props.max > 0}`]);
31
+ const whole = computed(() => number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) === void 0 || number(number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) === void 0 || number(1) === void 0 ? void 0 : number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) % number(1)) === void 0 ? void 0 : number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) - number(number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) === void 0 || number(1) === void 0 ? void 0 : number(number(percent.value) === void 0 || number(.5) === void 0 ? void 0 : number(percent.value) + number(.5)) % number(1)));
32
+ /** The values the styles' :host-state() rules test. */
33
+ const hostState = computed(() => [props.size && `size size=${props.size}`, props.tone && `tone tone=${props.tone}`].filter(Boolean).join(" "));
34
+ function text(value) {
35
+ if (Array.isArray(value)) return value.map(text).join(" ");
36
+ return value === null || value === void 0 || typeof value === "object" ? "" : String(value);
37
+ }
38
+ function attribute(value) {
39
+ if (value === null || value === void 0 || value === false || typeof value === "object" && !Array.isArray(value)) return void 0;
40
+ return value === true ? "" : text(value);
41
+ }
42
+ function number(value) {
43
+ return typeof value === "number" && !Number.isNaN(value) ? value : void 0;
44
+ }
45
+ return (_ctx, _cache) => {
46
+ return openBlock(), createElementBlock("span", mergeProps({
47
+ "data-component": "ui-meter",
48
+ role: "meter",
49
+ "aria-valuemin": "0"
50
+ }, _ctx.$attrs, {
51
+ "aria-valuemax": __props.max,
52
+ "aria-valuenow": amount.value,
53
+ "aria-valuetext": typeof {
54
+ true: __props.valueText,
55
+ false: `${whole.value ?? ""}%`
56
+ }[`${__props.valueText !== ""}`] === "boolean" ? String({
57
+ true: __props.valueText,
58
+ false: `${whole.value ?? ""}%`
59
+ }[`${__props.valueText !== ""}`]) : attribute({
60
+ true: __props.valueText,
61
+ false: `${whole.value ?? ""}%`
62
+ }[`${__props.valueText !== ""}`]),
63
+ "aria-label": typeof {
64
+ true: __props.label,
65
+ false: null
66
+ }[`${__props.label !== ""}`] === "boolean" ? String({
67
+ true: __props.label,
68
+ false: null
69
+ }[`${__props.label !== ""}`]) : attribute({
70
+ true: __props.label,
71
+ false: null
72
+ }[`${__props.label !== ""}`]),
73
+ "data-ui-meter-state": hostState.value || void 0
74
+ }), [createElementVNode("span", {
75
+ class: "fill",
76
+ style: normalizeStyle({ "inline-size": `${text(percent.value)}%` })
77
+ }, null, 4)], 16, _hoisted_1);
78
+ };
79
+ }
80
+ }), [["__scopeId", "data-v-f716cd47"]]);
81
+ //#endregion
82
+ export { UiMeter_default as t };
@@ -0,0 +1,40 @@
1
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
2
+ import { n as useComponentHost, t as createDispatch } from "./host.js";
3
+ import { computed, createElementBlock, defineComponent, mergeProps, openBlock, ref, renderSlot } from "vue";
4
+ import * as controllerModule from "@threadlabs/looma/components/ui-table/ui-table.js";
5
+ //#region .build/vue/UiTable.vue?vue&type=script&setup=true&lang.ts
6
+ var _hoisted_1 = ["data-ui-table-state"];
7
+ //#endregion
8
+ //#region .build/vue/UiTable.vue
9
+ var UiTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
10
+ inheritAttrs: false,
11
+ __name: "UiTable",
12
+ props: {
13
+ density: { default: "comfortable" },
14
+ stickyHeader: {
15
+ type: Boolean,
16
+ default: false
17
+ }
18
+ },
19
+ setup(__props) {
20
+ const props = __props;
21
+ const root = ref(null);
22
+ /** The values the styles' :host-state() rules test. */
23
+ const hostState = computed(() => [props.density && `density density=${props.density}`, props.stickyHeader && "stickyHeader"].filter(Boolean).join(" "));
24
+ const dispatch = createDispatch(root);
25
+ useComponentHost(controllerModule.default, {
26
+ root,
27
+ dispatch,
28
+ props
29
+ });
30
+ return (_ctx, _cache) => {
31
+ return openBlock(), createElementBlock("div", mergeProps({ "data-component": "ui-table" }, _ctx.$attrs, {
32
+ "data-ui-table-state": hostState.value || void 0,
33
+ ref_key: "root",
34
+ ref: root
35
+ }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_1);
36
+ };
37
+ }
38
+ }), [["__scopeId", "data-v-9980d203"]]);
39
+ //#endregion
40
+ export { UiTable_default as t };