@witchcraft/ui 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "witchcraftUi",
3
3
  "configKey": "witchcraftUi",
4
- "version": "0.3.12",
4
+ "version": "0.3.14",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -92,7 +92,7 @@
92
92
  </div>
93
93
  </div>
94
94
  <slot
95
- v-if="notification.message"
95
+ v-if="notification.message && !notification.component"
96
96
  name="message"
97
97
  v-bind="setSlotVar('message', {
98
98
  class: `
@@ -112,6 +112,21 @@
112
112
  {{ notification.message }}
113
113
  </div>
114
114
  </slot>
115
+ <Component
116
+ v-if="notification.component"
117
+ :is="notification.component"
118
+ v-bind="{
119
+ message: notification.message,
120
+ messageClasses: `
121
+ notification--message
122
+ whitespace-pre-wrap
123
+ text-neutral-800
124
+ dark:text-neutral-200
125
+ mb-1
126
+ `,
127
+ ...notification.componentProps ?? {}
128
+ }"
129
+ />
115
130
  <div class="notification--footer flex items-end justify-between">
116
131
  <div
117
132
  v-if="notification.code"
@@ -0,0 +1,6 @@
1
+ import type { CustomNotificationComponentProps } from "../../types/index.js";
2
+ type __VLS_Props = CustomNotificationComponentProps & {
3
+ customProp: string;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <div class="border-2 border-accent-500 p-1 px-2 rounded-sm bg-accent-500/10">
3
+ <div class="text-lg">
4
+ Custom Message Component
5
+ </div>
6
+ <div class="font-bold">
7
+ Original message:
8
+ </div>
9
+ <div
10
+ :class="props.messageClasses"
11
+ >
12
+ {{ props.message }}
13
+ </div>
14
+ <div class="font-bold">
15
+ Custom Prop:
16
+ </div>
17
+ <div>
18
+ {{ props.customProp }}
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup>
24
+ const props = defineProps({
25
+ message: { type: String, required: true },
26
+ messageClasses: { type: String, required: false },
27
+ customProp: { type: String, required: true }
28
+ });
29
+ </script>
@@ -0,0 +1,6 @@
1
+ import type { CustomNotificationComponentProps } from "../../types/index.js";
2
+ type __VLS_Props = CustomNotificationComponentProps & {
3
+ customProp: string;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
@@ -25,6 +25,7 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
25
25
  slots: {
26
26
  [x: string]: ((props: {
27
27
  colKey: any;
28
+ config: any;
28
29
  style: string;
29
30
  class: string;
30
31
  }) => any) | undefined;
@@ -61,6 +61,7 @@
61
61
  ].join(' ')"
62
62
  :style="`width:${widths.length > 0 ? widths[i] : ``}; `"
63
63
  :col-key="col"
64
+ :config="colConfig[col]"
64
65
  >
65
66
  <td
66
67
  :class="[
@@ -145,7 +146,7 @@ const getExtraClasses = (row, col, isHeader) => {
145
146
  const extraClasses = computed(() => Object.fromEntries(
146
147
  [...Array(props.values.length + 1).keys()].map((row) => [...Array(props.cols.length).keys()].map((col) => [
147
148
  `${row - 1}-${col}`,
148
- getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" ")
149
+ " " + getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" ") + " "
149
150
  ])).flat()
150
151
  ));
151
152
  </script>
@@ -25,6 +25,7 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
25
25
  slots: {
26
26
  [x: string]: ((props: {
27
27
  colKey: any;
28
+ config: any;
28
29
  style: string;
29
30
  class: string;
30
31
  }) => any) | undefined;
@@ -1,5 +1,5 @@
1
1
  import type { AnyFunction, MakeRequired } from "@alanscodelog/utils";
2
- import { type Reactive } from "vue";
2
+ import { type Component, type Reactive } from "vue";
3
3
  export declare class NotificationHandler<TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>, TEntry extends NotificationEntry<TRawEntry> = NotificationEntry<TRawEntry>> {
4
4
  timeout: number;
5
5
  debug: boolean;
@@ -26,7 +26,6 @@ export declare class NotificationHandler<TRawEntry extends RawNotificationEntry<
26
26
  }
27
27
  export type NotificationPromise<TOption extends string = string> = Promise<TOption>;
28
28
  export type RawNotificationEntry<TOptions extends string[] = ["Ok", "Cancel"], TCancellable extends boolean | TOptions[number] = "Cancel"> = {
29
- message: string;
30
29
  title?: string;
31
30
  code?: string;
32
31
  /** @default ["Ok", "Cancel"] */
@@ -41,6 +40,10 @@ export type RawNotificationEntry<TOptions extends string[] = ["Ok", "Cancel"], T
41
40
  /** @default false if cancellable, otherwise the default timeout */
42
41
  timeout?: number | boolean;
43
42
  icon?: string;
43
+ message: string;
44
+ component?: string | Component;
45
+ /** By default the component is passed the message and the messageClasses. Both will be overriden if you set them on componentProps. */
46
+ componentProps?: Record<string, any>;
44
47
  };
45
48
  export type NotificationEntry<TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>> = Omit<MakeRequired<TRawEntry, "options" | "requiresAction" | "default" | "dangerous">, "cancellable"> & {
46
49
  promise: NotificationPromise;
@@ -4,7 +4,7 @@ import { indent } from "@alanscodelog/utils/indent";
4
4
  import { isBlank } from "@alanscodelog/utils/isBlank";
5
5
  import { pretty } from "@alanscodelog/utils/pretty";
6
6
  import { setReadOnly } from "@alanscodelog/utils/setReadOnly";
7
- import { reactive } from "vue";
7
+ import { markRaw, reactive } from "vue";
8
8
  export class NotificationHandler {
9
9
  timeout = 5e3;
10
10
  debug = false;
@@ -87,6 +87,7 @@ export class NotificationHandler {
87
87
  default: "Ok",
88
88
  cancellable: rawEntry.cancellable,
89
89
  ...rawEntry,
90
+ component: rawEntry.component && typeof rawEntry.component !== "string" ? markRaw(rawEntry.component) : void 0,
90
91
  dangerous: rawEntry.dangerous ?? [],
91
92
  timeout: rawEntry.timeout === true ? this.timeout : rawEntry.timeout !== void 0 && rawEntry.timeout !== false ? rawEntry.timeout : void 0
92
93
  };
@@ -123,3 +123,7 @@ export type RangeDate = {
123
123
  start?: SingleDate;
124
124
  end?: SingleDate;
125
125
  };
126
+ export type CustomNotificationComponentProps = {
127
+ message: string;
128
+ messageClasses?: string;
129
+ };
@@ -1,3 +1,4 @@
1
+ import type { NotificationEntry } from "../helpers/NotificationHandler.js";
1
2
  /**
2
3
  * Notifies the user if the given value is an error. Useful for making non-critical errors don't go unnoticed.
3
4
  *
@@ -5,10 +6,11 @@
5
6
  *
6
7
  * If the value is not an error, it is returned.
7
8
  */
8
- export declare function notifyIfError<T>(err: T, { logger, ns, force }?: {
9
+ export declare function notifyIfError<T>(err: T, { logger, ns, force, entry }?: {
9
10
  logger?: {
10
11
  debug: (...args: any[]) => void;
11
12
  };
12
13
  ns?: string;
13
14
  force?: boolean;
15
+ entry?: Partial<NotificationEntry<any>>;
14
16
  }): T;
@@ -3,7 +3,8 @@ import { useNotificationHandler } from "../composables/useNotificationHandler.js
3
3
  export function notifyIfError(err, {
4
4
  logger,
5
5
  ns,
6
- force = false
6
+ force = false,
7
+ entry
7
8
  } = {}) {
8
9
  if (force || err instanceof Error) {
9
10
  const errMessage = {
@@ -22,7 +23,8 @@ export function notifyIfError(err, {
22
23
  ...errMessage,
23
24
  options: ["Ok"],
24
25
  cancellable: "Ok",
25
- timeout: true
26
+ timeout: true,
27
+ ...entry
26
28
  });
27
29
  }
28
30
  return err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@witchcraft/ui",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "Vue component library.",
5
5
  "type": "module",
6
6
  "main": "./dist/runtime/main.lib.js",
@@ -2,6 +2,7 @@
2
2
  import type { Meta, StoryObj } from "@storybook/vue3"
3
3
 
4
4
  import LibNotification from "./LibNotification.vue"
5
+ import LibNotificationTestMessageComponent from "./LibNotificationTestMessageComponent.vue"
5
6
 
6
7
  import { NotificationHandler } from "../../helpers/NotificationHandler.js"
7
8
  import * as components from "../index.js"
@@ -21,7 +22,11 @@ type Story = StoryObj<typeof LibNotification>
21
22
 
22
23
  export const Primary: Story = {
23
24
  render: args => ({
24
- components: { ...components, LibNotification },
25
+ components: {
26
+ ...components,
27
+ LibNotification,
28
+ LibNotificationTestMessageComponent
29
+ },
25
30
  setup() {
26
31
  return { args }
27
32
  },
@@ -136,3 +141,19 @@ export const CustomDefaultAndDangerousOption: Story = {
136
141
  })
137
142
  }
138
143
  }
144
+
145
+
146
+ export const CustomMessageComponent: Story = {
147
+ ...Primary,
148
+ args: {
149
+ ...Primary.args,
150
+ // @ts-expect-error calling protected method
151
+ notification: handler._createEntry({
152
+ ...Primary.args!.notification,
153
+ component: LibNotificationTestMessageComponent,
154
+ componentProps: {
155
+ customProp: "Custom Prop"
156
+ }
157
+ })
158
+ }
159
+ }
@@ -90,7 +90,7 @@
90
90
  </div>
91
91
  </div>
92
92
  <slot
93
- v-if="notification.message"
93
+ v-if="notification.message && !notification.component"
94
94
  name="message"
95
95
  v-bind="setSlotVar('message', {
96
96
  class: `
@@ -110,6 +110,21 @@
110
110
  {{ notification.message }}
111
111
  </div>
112
112
  </slot>
113
+ <Component
114
+ v-if="notification.component"
115
+ :is="notification.component"
116
+ v-bind="{
117
+ message: notification.message,
118
+ messageClasses: `
119
+ notification--message
120
+ whitespace-pre-wrap
121
+ text-neutral-800
122
+ dark:text-neutral-200
123
+ mb-1
124
+ `,
125
+ ...(notification.componentProps ?? {})
126
+ }"
127
+ />
113
128
  <div class="notification--footer flex items-end justify-between">
114
129
  <div
115
130
  v-if="notification.code"
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <div class="border-2 border-accent-500 p-1 px-2 rounded-sm bg-accent-500/10">
3
+ <div class="text-lg">
4
+ Custom Message Component
5
+ </div>
6
+ <div class="font-bold">
7
+ Original message:
8
+ </div>
9
+ <div
10
+ :class="props.messageClasses"
11
+ >
12
+ {{ props.message }}
13
+ </div>
14
+ <div class="font-bold">
15
+ Custom Prop:
16
+ </div>
17
+ <div>
18
+ {{ props.customProp }}
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import type { CustomNotificationComponentProps } from "../../types/index.js"
25
+
26
+ const props = defineProps<CustomNotificationComponentProps & { customProp: string }>()
27
+ </script>
@@ -7,12 +7,12 @@ import LibTable from "./LibTable.vue"
7
7
  import * as components from "../index.js"
8
8
 
9
9
  const meta: Meta<typeof LibTable> = {
10
- component: LibTable,
10
+ component: LibTable as any,
11
11
  title: "Components/Table"
12
12
  }
13
13
 
14
14
  export default meta
15
- type Story = StoryObj<typeof LibTable>
15
+ type Story = StoryObj<typeof LibTable> & { args: { slots?: string } }
16
16
  export const Primary: Story = {
17
17
  render: args => ({
18
18
  components,
@@ -22,6 +22,7 @@ export const Primary: Story = {
22
22
  <lib-table
23
23
  v-bind="args"
24
24
  >
25
+ ${(args as any).slots}
25
26
  </lib-table>
26
27
  </div>
27
28
  `
@@ -91,6 +92,38 @@ export const NoHeaderNoCellBorders: Story = {
91
92
  cellBorder: false
92
93
  }
93
94
  }
95
+
96
+ export const InitialSize: Story = {
97
+ ...Primary,
98
+ args: {
99
+ ...Primary.args,
100
+ colConfig: {
101
+ prop1: { name: "Initially Flex 1", resizable: true },
102
+ prop2: { name: "Initially Flex 2", resizable: true },
103
+ prop3: { name: "Initially Size of Header", resizable: true }
104
+ },
105
+ resizable: {
106
+ enabled: true
107
+ },
108
+ class: `
109
+ [&:not(.resizable-cols-setup)]:block
110
+ [&:not(.resizable-cols-setup)_thead]:block
111
+ [&:not(.resizable-cols-setup)_thead_tr]:w-full
112
+ [&:not(.resizable-cols-setup)_thead_tr]:flex
113
+ [&:not(.resizable-cols-setup)_thead_tr]:flex-nowrap
114
+ [&:not(.resizable-cols-setup)_thead_td:not(.override-initial)]:flex-1
115
+ `,
116
+ slots: `
117
+ <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>
124
+ `
125
+ }
126
+ }
94
127
  export const FitWidthFalse: Story = {
95
128
  ...Primary,
96
129
  args: {
@@ -61,6 +61,7 @@
61
61
  ].join(' ')"
62
62
  :style="`width:${widths.length > 0 ? widths[i] : ``}; `"
63
63
  :col-key="col"
64
+ :config="(colConfig as any)[col]"
64
65
  >
65
66
  <td
66
67
  :class="[
@@ -160,7 +161,7 @@ const extraClasses = computed(() => Object.fromEntries([...Array(props.values.le
160
161
  .map(col =>
161
162
  [
162
163
  `${row - 1}-${col}`,
163
- getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" ")
164
+ " " + getExtraClasses(row <= 0 ? 0 : row - 1, col, row === 0).join(" ") + " "
164
165
  ]))
165
166
  .flat()
166
167
  ))
@@ -5,7 +5,7 @@ import { indent } from "@alanscodelog/utils/indent"
5
5
  import { isBlank } from "@alanscodelog/utils/isBlank"
6
6
  import { pretty } from "@alanscodelog/utils/pretty"
7
7
  import { setReadOnly } from "@alanscodelog/utils/setReadOnly"
8
- import { type Reactive, reactive } from "vue"
8
+ import { type Component, markRaw, type Reactive, reactive } from "vue"
9
9
 
10
10
  export class NotificationHandler<
11
11
  TRawEntry extends RawNotificationEntry<any, any> = RawNotificationEntry<any, any>,
@@ -99,6 +99,7 @@ export class NotificationHandler<
99
99
  default: "Ok",
100
100
  cancellable: rawEntry.cancellable,
101
101
  ...rawEntry,
102
+ component: rawEntry.component && typeof rawEntry.component !== "string" ? markRaw(rawEntry.component) : undefined,
102
103
  dangerous: rawEntry.dangerous ?? [],
103
104
  timeout: rawEntry.timeout === true
104
105
  ? this.timeout
@@ -211,7 +212,6 @@ export type RawNotificationEntry<
211
212
  TOptions extends string[] = ["Ok", "Cancel"],
212
213
  TCancellable extends boolean | TOptions[number] = "Cancel"
213
214
  > = {
214
- message: string
215
215
  title?: string
216
216
  code?: string
217
217
  /** @default ["Ok", "Cancel"] */
@@ -226,6 +226,10 @@ export type RawNotificationEntry<
226
226
  /** @default false if cancellable, otherwise the default timeout */
227
227
  timeout?: number | boolean
228
228
  icon?: string
229
+ message: string
230
+ component?: string | Component
231
+ /** By default the component is passed the message and the messageClasses. Both will be overriden if you set them on componentProps. */
232
+ componentProps?: Record<string, any>
229
233
  }
230
234
 
231
235
  export type NotificationEntry<
@@ -118,3 +118,8 @@ export type RangeDate = {
118
118
  start?: SingleDate
119
119
  end?: SingleDate
120
120
  }
121
+
122
+ export type CustomNotificationComponentProps = {
123
+ message: string
124
+ messageClasses?: string
125
+ }
@@ -1,6 +1,7 @@
1
1
  import { TypedError } from "@alanscodelog/utils/TypedError"
2
2
 
3
3
  import { useNotificationHandler } from "../composables/useNotificationHandler.js"
4
+ import type { NotificationEntry } from "../helpers/NotificationHandler.js"
4
5
 
5
6
  /**
6
7
  * Notifies the user if the given value is an error. Useful for making non-critical errors don't go unnoticed.
@@ -13,13 +14,15 @@ export function notifyIfError<T>(
13
14
  err: T, {
14
15
  logger,
15
16
  ns,
16
- force = false
17
+ force = false,
18
+ entry
17
19
  }: {
18
20
  logger?: { debug: (...args: any[]) => void }
19
21
  /* Logger namespace. */
20
22
  ns?: string
21
23
  /* force interpret as error, for catch blocks */
22
24
  force?: boolean
25
+ entry?: Partial<NotificationEntry<any>>
23
26
  } = {}): T {
24
27
  if (force || err instanceof Error) {
25
28
  const errMessage = {
@@ -38,7 +41,8 @@ export function notifyIfError<T>(
38
41
  ...errMessage,
39
42
  options: ["Ok"],
40
43
  cancellable: "Ok",
41
- timeout: true
44
+ timeout: true,
45
+ ...entry
42
46
  })
43
47
  }
44
48
  return err