@witchcraft/ui 0.3.14 → 0.3.16

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.
@@ -1,25 +1,58 @@
1
1
  /* eslint-disable @typescript-eslint/naming-convention */
2
+ import { faker } from "@faker-js/faker"
2
3
  import type { Meta, StoryObj } from "@storybook/vue3"
4
+ import { reactive, ref } from "vue"
3
5
 
4
6
  import LibTable from "./LibTable.vue"
5
7
 
6
8
  // todo
7
9
  import * as components from "../index.js"
8
10
 
11
+ // faker is slow, we can just choose from a few hundred pre-generated sentences
12
+ const fakerSentences = Array.from({ length: 100 }).fill(0).map(_ => faker.lorem.sentence(faker.number.int({ min: 1, max: 50 })))
13
+
9
14
  const meta: Meta<typeof LibTable> = {
10
15
  component: LibTable as any,
11
16
  title: "Components/Table"
12
17
  }
13
18
 
14
19
  export default meta
15
- type Story = StoryObj<typeof LibTable> & { args: { slots?: string } }
20
+ type Story = StoryObj<typeof LibTable> & { args: {
21
+ slots?: string
22
+ wrapperClass?: string
23
+ } }
16
24
  export const Primary: Story = {
17
25
  render: args => ({
18
26
  components,
19
- setup: () => ({ args }),
27
+ setup: () => {
28
+ const show = ref(true)
29
+ const debugGrips = ref(false)
30
+ // careful, storybook passes refs as is causing issues
31
+ const argsReactive = reactive({
32
+ ...args,
33
+ resizable: {
34
+ enabled: true,
35
+ ...args.resizable
36
+ }
37
+ })
38
+
39
+ return {
40
+ args: argsReactive,
41
+ debugGrips,
42
+ show
43
+ }
44
+ },
20
45
  template: `
21
- <div class="overflow-x-scroll scrollbar-hidden">
46
+ <div class="p-2 flex flex-col gap-2 border rounded-md mb-10">
47
+ Controls:
48
+ <LibButton class="flex-1" @click="args.resizable.enabled = !args.resizable.enabled">Toggle Resizable (currently {{args.resizable.enabled}})</LibButton>
49
+ <LibButton @click="args.stickyHeader = !args.stickyHeader">Toggle Sticky Header (currently {{args.stickyHeader}})</LibButton>
50
+ <LibButton @click="show = !show">Toggle Table</LibButton>
51
+ <LibButton @click="debugGrips = !debugGrips">Toggle Debug Grips (currently {{debugGrips}})</LibButton>
52
+ </div>
53
+ <div :class="debugGrips ? ' [&_.grip]:bg-red-500': ''">
22
54
  <lib-table
55
+ v-if="show"
23
56
  v-bind="args"
24
57
  >
25
58
  ${(args as any).slots}
@@ -34,8 +67,7 @@ export const Primary: Story = {
34
67
  { prop1: "Item2 Prop 1", prop2: "Item2 Prop 2", prop3: "Item2 Prop 3" },
35
68
  { prop1: "Item3 Prop 1", prop2: "Item3 Prop 2", prop3: "Item3 Prop 3" }
36
69
  ],
37
- colConfig: { prop1: { name: "Header 1" }, prop2: { name: "Header 2" } },
38
- itemKey: "prop1"
70
+ colConfig: { prop1: { name: "Header 1" }, prop2: { name: "Header 2" } }
39
71
  }
40
72
  }
41
73
 
@@ -46,6 +78,7 @@ export const NoCellBorders: Story = {
46
78
  cellBorder: false
47
79
  }
48
80
  }
81
+
49
82
  export const NoBorders: Story = {
50
83
  ...Primary,
51
84
  args: {
@@ -106,24 +139,27 @@ export const InitialSize: Story = {
106
139
  enabled: true
107
140
  },
108
141
  class: `
142
+ [&:not(.resizable-cols-setup)]:w-full
109
143
  [&:not(.resizable-cols-setup)]:block
110
144
  [&:not(.resizable-cols-setup)_thead]:block
111
145
  [&:not(.resizable-cols-setup)_thead_tr]:w-full
112
146
  [&:not(.resizable-cols-setup)_thead_tr]:flex
113
147
  [&:not(.resizable-cols-setup)_thead_tr]:flex-nowrap
114
- [&:not(.resizable-cols-setup)_thead_td:not(.override-initial)]:flex-1
148
+ [&:not(.resizable-cols-setup)_thead_th:not(.override-initial)]:flex-1
115
149
  `,
116
150
  slots: `
117
151
  <template #header-prop3="colProps">
118
- <td
119
- :class="\`\${colProps.class} w-[min-content] whitespace-nowrap override-initial\`"
120
- >
121
- {{ colProps.config.name }}
122
- </td>
123
- </template>
152
+ <th
153
+ :class="\`\${colProps.class} [table:not(.resizable-cols-setup)_&]:w-[min-content] whitespace-nowrap override-initial\`"
154
+ :style="colProps.style"
155
+ >
156
+ {{ colProps.config.name }}
157
+ </th>
158
+ </template>
124
159
  `
125
160
  }
126
161
  }
162
+
127
163
  export const FitWidthFalse: Story = {
128
164
  ...Primary,
129
165
  args: {
@@ -134,59 +170,148 @@ export const FitWidthFalse: Story = {
134
170
  }
135
171
  }
136
172
 
137
- export const ThreeColSomeColsNotResizable: Story = {
138
- render: args => ({
139
- components,
140
- setup: () => ({ args }),
141
- template: `
142
- <lib-table
143
- v-bind="args"
144
- >
145
- </lib-table>
146
- <br>
147
- <lib-table
148
- v-bind="{...args, colConfig:args.colConfig2}"
149
- >
150
- </lib-table>
151
- <br>
152
- <lib-table
153
- v-bind="{...args, colConfig:args.colConfig3}"
154
- >
155
- </lib-table>
156
- `
157
- }),
173
+
174
+ export const StickyHeader: Story = {
175
+ ...Primary,
158
176
  args: {
159
- cols: ["prop1", "prop2", "prop3"],
160
- itemKey: "prop1",
161
- values: [
162
- { prop1: "Prop 1", prop2: "Prop 2", prop3: "Prop 3" }
163
- ],
164
- colConfig: { prop1: { name: "No Resize", resizable: false } },
165
- colConfig2: { prop2: { name: "No Resize", resizable: false } },
166
- colConfig3: { prop3: { name: "No Resize", resizable: false } }
167
- } as any
177
+ ...Primary.args,
178
+ resizable: {
179
+ enabled: true
180
+ },
181
+ stickyHeader: true,
182
+ // moving the border to the wrapper is to hide the little bits of border sticking out
183
+ // added back the right straight border otherwise the scrollbar looks ass
184
+ // this is ever so slightly visible if there is no scrollbar
185
+ wrapperClass: `
186
+ max-h-[50dvh]
187
+ `,
188
+ values: Array.from({ length: 200 }).fill(0).map((_, i) => ({
189
+ prop1: `Item${i + 1} Prop 1`,
190
+ prop2: `Item${i + 1} Prop 2`,
191
+ prop3: `Item${i + 1} Prop 3`
192
+ }))
193
+ }
168
194
  }
169
- export const FourColSomeColsNotResizable: Story = {
195
+
196
+
197
+ export const VirtualizedFixedHeight: Story = {
198
+ ...Primary,
199
+ args: {
200
+ ...Primary.args,
201
+ resizable: {
202
+ enabled: true
203
+ },
204
+ virtualizerOptions: {
205
+ enabled: true
206
+ },
207
+ stickyHeader: true,
208
+ wrapperClass: `
209
+ max-h-[50dvh]
210
+ `,
211
+ values: Array.from({ length: 10000 }).fill(0).map((_, i) => ({
212
+ prop1: `Item${i + 1} Prop 1`,
213
+ prop2: `Item${i + 1} Prop 2`,
214
+ prop3: `Item${i + 1} Prop 3`
215
+ }))
216
+ }
217
+ }
218
+
219
+
220
+ // this is not the smoothest ever, but then the tan stack example isn't either
221
+ // i think the issue is when the scrollbar gets to it's min height
222
+ export const VirtualizedDynamicHeightExperimental: Story = {
223
+ ...VirtualizedFixedHeight,
224
+ args: {
225
+ ...VirtualizedFixedHeight.args,
226
+ virtualizerOptions: {
227
+ enabled: true,
228
+ method: "dynamic",
229
+ overscan: 5 // overscan is more expensive in dynamic mode
230
+ },
231
+ class: `
232
+ [&_td]:no-truncate!
233
+ [&_th]:no-truncate!
234
+ `,
235
+ values: Array.from({ length: 10000 }).fill(0).map((_, i) => ({
236
+ prop1: `Item${i + 1} Prop 1: ${faker.helpers.arrayElement(fakerSentences)}`,
237
+ prop2: `Item${i + 1} Prop 2: ${faker.helpers.arrayElement(fakerSentences)}`,
238
+ prop3: `Item${i + 1} Prop 3: ${faker.helpers.arrayElement(fakerSentences)}`
239
+ }))
240
+ },
241
+ parameters: {
242
+ tags: ["skip-smoke-test"]
243
+ }
244
+ }
245
+
246
+
247
+ export const VirtualizedFitWidthFalse: Story = {
248
+ ...VirtualizedFixedHeight,
249
+ args: {
250
+ ...VirtualizedFixedHeight.args,
251
+ resizable: {
252
+ fitWidth: false
253
+ },
254
+
255
+ class: `
256
+ [&_th]:no-truncate!
257
+ [&_th]:whitespace-nowrap!
258
+ [&:not(.resizable-cols-setup)]:w-max
259
+ [&:not(.resizable-cols-setup)_th]:w-max
260
+ `,
261
+ wrapperClass: `
262
+ max-h-[50dvh]
263
+ `,
264
+ values: Array.from({ length: 10000 }).fill(0).map((_, i) => ({
265
+ prop1: `Item${i + 1} Prop 1`,
266
+ prop2: `Item${i + 1} Prop 2`,
267
+ prop3: `Item${i + 1} Prop 3`
268
+ }))
269
+
270
+ }
271
+ }
272
+
273
+ export const ThreeColSomeColsNotResizable: Story = {
170
274
  render: args => ({
171
275
  components,
172
- setup: () => ({ args }),
276
+ setup: () => {
277
+ const debugGrips = ref(false)
278
+ return { args, debugGrips }
279
+ },
173
280
  template: `
281
+ <div class="flex flex-col gap-2 w-full border rounded-md mb-10">
282
+ <WButton @click="debugGrips = !debugGrips">Toggle Debug Grips (currently {{debugGrips}})</WButton>
283
+ </div>
284
+ <div :class="debugGrips ? ' [&_.grip]:bg-red-500': ''">
285
+ <div class="flex flex-col gap-2 w-full">
174
286
  <lib-table
175
287
  v-bind="args"
176
288
  >
177
289
  </lib-table>
178
- <br>
179
290
  <lib-table
180
291
  v-bind="{...args, colConfig:args.colConfig2}"
181
292
  >
182
- </lib-table>
183
- <br>
293
+ </lib-table>
184
294
  <lib-table
185
295
  v-bind="{...args, colConfig:args.colConfig3}"
186
296
  >
187
297
  </lib-table>
298
+ </div>
299
+ </div>
188
300
  `
189
301
  }),
302
+ args: {
303
+ cols: ["prop1", "prop2", "prop3"],
304
+ itemKey: "prop1",
305
+ values: [
306
+ { prop1: "Prop 1", prop2: "Prop 2", prop3: "Prop 3" }
307
+ ],
308
+ colConfig: { prop1: { name: "No Resize", resizable: false } },
309
+ colConfig2: { prop2: { name: "No Resize", resizable: false } },
310
+ colConfig3: { prop3: { name: "No Resize", resizable: false } }
311
+ } as any
312
+ }
313
+ export const FourColSomeColsNotResizable: Story = {
314
+ render: ThreeColSomeColsNotResizable.render,
190
315
  args: {
191
316
  cols: ["prop1", "prop2", "prop3", "prop4"],
192
317
  values: [