@dosgato/dialog 1.2.7 → 1.3.0

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/Button.svelte +15 -13
  2. package/dist/ButtonGroup.svelte +44 -40
  3. package/dist/Checkbox.svelte +13 -12
  4. package/dist/Container.svelte +50 -46
  5. package/dist/Dialog.svelte +56 -41
  6. package/dist/FieldAutocomplete.svelte +77 -70
  7. package/dist/FieldCheckbox.svelte +25 -22
  8. package/dist/FieldChoices.svelte +74 -68
  9. package/dist/FieldChooserLink.svelte +148 -150
  10. package/dist/FieldDate.svelte +19 -18
  11. package/dist/FieldDateTime.svelte +36 -34
  12. package/dist/FieldDualListbox.svelte +80 -79
  13. package/dist/FieldHidden.svelte +16 -15
  14. package/dist/FieldIdentifier.svelte +18 -17
  15. package/dist/FieldMultiple.svelte +71 -74
  16. package/dist/FieldMultiselect.svelte +86 -59
  17. package/dist/FieldMultiselect.svelte.d.ts +13 -1
  18. package/dist/FieldNumber.svelte +20 -19
  19. package/dist/FieldRadio.svelte +42 -41
  20. package/dist/FieldSelect.svelte +45 -45
  21. package/dist/FieldStandard.svelte +28 -27
  22. package/dist/FieldText.svelte +27 -24
  23. package/dist/FieldTextArea.svelte +24 -24
  24. package/dist/FileIcon.svelte +10 -8
  25. package/dist/Form.svelte +40 -18
  26. package/dist/Form.svelte.d.ts +15 -13
  27. package/dist/FormDialog.svelte +40 -25
  28. package/dist/FormDialog.svelte.d.ts +23 -17
  29. package/dist/Icon.svelte +38 -33
  30. package/dist/InlineMessage.svelte +31 -29
  31. package/dist/InlineMessages.svelte +10 -7
  32. package/dist/Input.svelte +40 -39
  33. package/dist/Listbox.svelte +102 -109
  34. package/dist/MaxLength.svelte +19 -18
  35. package/dist/Radio.svelte +18 -15
  36. package/dist/Switcher.svelte +37 -33
  37. package/dist/Tab.svelte +23 -21
  38. package/dist/Tabs.svelte +111 -110
  39. package/dist/Tooltip.svelte +7 -7
  40. package/dist/chooser/Chooser.svelte +83 -76
  41. package/dist/chooser/ChooserPreview.svelte +16 -14
  42. package/dist/chooser/Details.svelte +6 -4
  43. package/dist/chooser/Thumbnail.svelte +20 -16
  44. package/dist/chooser/UploadUI.svelte +78 -69
  45. package/dist/code/CodeEditor.svelte +63 -66
  46. package/dist/code/FieldCodeEditor.svelte +21 -19
  47. package/dist/colorpicker/FieldColorPicker.svelte +36 -35
  48. package/dist/cropper/FieldCropper.svelte +142 -141
  49. package/dist/iconpicker/FieldIconPicker.svelte +102 -94
  50. package/dist/imageposition/FieldImagePosition.svelte +107 -98
  51. package/dist/tagpicker/FieldTagPicker.svelte +104 -38
  52. package/dist/tagpicker/FieldTagPicker.svelte.d.ts +7 -0
  53. package/dist/tree/LoadIcon.svelte +0 -1
  54. package/dist/tree/Tree.svelte +198 -192
  55. package/dist/tree/Tree.svelte.d.ts +5 -5
  56. package/dist/tree/TreeCell.svelte +10 -6
  57. package/dist/tree/TreeCell.svelte.d.ts +5 -5
  58. package/dist/tree/TreeNode.svelte +213 -241
  59. package/dist/tree/TreeNode.svelte.d.ts +5 -5
  60. package/package.json +9 -10
@@ -1,22 +1,24 @@
1
- <script>export let maxlength;
2
- export let value;
3
- let overLimit = false;
4
- $: message = getMaxlengthMessage(value.length);
5
- function getMaxlengthMessage(length) {
6
- overLimit = false;
1
+ <script lang="ts">
2
+ export let maxlength: number
3
+ export let value: string
4
+
5
+ let overLimit = false
6
+
7
+ $: message = getMaxlengthMessage(value.length)
8
+
9
+ function getMaxlengthMessage (length: number) {
10
+ overLimit = false
7
11
  if (length === 0) {
8
- return `${maxlength} characters allowed`;
9
- }
10
- else if (length <= maxlength) {
11
- const diff = maxlength - length;
12
- return `${diff} character${diff === 1 ? '' : 's'} remaining`;
12
+ return `${maxlength} characters allowed`
13
+ } else if (length <= maxlength) {
14
+ const diff = maxlength - length
15
+ return `${diff} character${diff === 1 ? '' : 's'} remaining`
16
+ } else {
17
+ overLimit = true
18
+ const diff = length - maxlength
19
+ return `${diff} character${diff === 1 ? '' : 's'} over limit`
13
20
  }
14
- else {
15
- overLimit = true;
16
- const diff = length - maxlength;
17
- return `${diff} character${diff === 1 ? '' : 's'} over limit`;
18
- }
19
- }
21
+ }
20
22
  </script>
21
23
 
22
24
  <div class:over={overLimit} aria-live="polite">{message}</div>
@@ -32,5 +34,4 @@ function getMaxlengthMessage(length) {
32
34
  color: #9a3332;
33
35
  font-weight: bold;
34
36
  }
35
-
36
37
  </style>
package/dist/Radio.svelte CHANGED
@@ -1,17 +1,21 @@
1
- <script>import { isNotBlank } from 'txstate-utils';
2
- export let id = undefined;
3
- export let name;
4
- export let value;
5
- export let selected = false;
6
- export let onChange = undefined;
7
- export let onBlur = undefined;
8
- export let messagesid = undefined;
9
- export let helptextid = undefined;
10
- export let extradescid = undefined;
11
- export let disabled = false;
12
- export let valid = false;
13
- export let invalid = false;
14
- $: descby = [messagesid, helptextid, extradescid].filter(isNotBlank).join(' ');
1
+ <script lang="ts">
2
+ import { isNotBlank } from 'txstate-utils'
3
+
4
+
5
+ export let id: string | undefined = undefined
6
+ export let name: string
7
+ export let value: string
8
+ export let selected = false
9
+ export let onChange: any = undefined
10
+ export let onBlur: any = undefined
11
+ export let messagesid: string | undefined = undefined
12
+ export let helptextid: string | undefined = undefined
13
+ export let extradescid: string | undefined = undefined
14
+ export let disabled = false
15
+ export let valid = false
16
+ export let invalid = false
17
+
18
+ $: descby = [messagesid, helptextid, extradescid].filter(isNotBlank).join(' ')
15
19
  </script>
16
20
 
17
21
  <input {id} type="radio" {name} class:valid class:invalid checked={selected} {disabled} aria-describedby={descby} {value} on:change={onChange} on:blur={onBlur}>
@@ -66,5 +70,4 @@ input[type="radio"]:disabled {
66
70
  color: var(--dialog-checkbox-color);
67
71
  cursor: not-allowed;
68
72
  }
69
-
70
73
  </style>
@@ -1,35 +1,40 @@
1
- <script>import { eq } from '@txstate-mws/svelte-components';
2
- import { Store } from '@txstate-mws/svelte-store';
3
- import { createEventDispatcher } from 'svelte';
4
- import { randomid } from 'txstate-utils';
5
- import Container from './Container.svelte';
6
- import Radio from './Radio.svelte';
7
- let className = '';
8
- export { className as class };
9
- export let id = randomid();
10
- export let path = '';
11
- export let name = randomid();
12
- export let choices;
13
- export let horizontal = false;
14
- export let label;
15
- export let required = false;
16
- export let related = 0;
17
- export let extradescid = undefined;
18
- export let helptext = undefined;
19
- export let messages = [];
20
- export let iptValue = choices[0].value;
21
- export let valid = false;
22
- export let invalid = false;
23
- export let onBlur = undefined;
24
- const dispatch = createEventDispatcher();
25
- const store = new Store({ width: 1000 });
26
- const groupid = randomid();
27
- function onChange(e) {
28
- iptValue = this.value;
29
- dispatch('change', iptValue);
30
- }
31
- $: columns = Math.floor($store.width / 250);
32
- $: width = (horizontal ? 100 / Math.min(choices.length, choices.length === 4 && columns === 3 ? 2 : columns) : 100) + '%';
1
+ <script lang="ts">
2
+ import { eq } from '@txstate-mws/svelte-components'
3
+ import type { Feedback } from '@txstate-mws/svelte-forms'
4
+ import { Store } from '@txstate-mws/svelte-store'
5
+ import { createEventDispatcher } from 'svelte'
6
+ import { randomid } from 'txstate-utils'
7
+ import Container from './Container.svelte'
8
+ import Radio from './Radio.svelte'
9
+ let className = ''
10
+ export { className as class }
11
+ export let id: string | undefined = randomid()
12
+ export let path: string = ''
13
+ export let name = randomid()
14
+ export let choices: { label?: string, value: string, disabled?: boolean }[]
15
+ export let horizontal = false
16
+ export let label: string
17
+ export let required = false
18
+ export let related: true | number = 0
19
+ export let extradescid: string | undefined = undefined
20
+ export let helptext: string | undefined = undefined
21
+ export let messages: Feedback[] = []
22
+ export let iptValue = choices[0].value
23
+ export let valid = false
24
+ export let invalid = false
25
+ export let onBlur: (() => void | Promise<void>) | undefined = undefined
26
+
27
+ const dispatch = createEventDispatcher()
28
+ const store = new Store({ width: 1000 })
29
+
30
+ const groupid = randomid()
31
+ function onChange (e: InputEvent) {
32
+ iptValue = this.value
33
+ dispatch('change', iptValue)
34
+ }
35
+
36
+ $: columns = Math.floor($store.width / 250)
37
+ $: width = (horizontal ? 100 / Math.min(choices.length, choices.length === 4 && columns === 3 ? 2 : columns) : 100) + '%'
33
38
  </script>
34
39
  <Container {path} {id} {label} {messages} descid={groupid} {required} {related} {helptext} let:helptextid>
35
40
  <div class="dialog-radio {className}" use:eq={{ store }} class:horizontal role="radiogroup" aria-labelledby={groupid} class:valid class:invalid>
@@ -66,5 +71,4 @@ $: width = (horizontal ? 100 / Math.min(choices.length, choices.length === 4 &&
66
71
  display: flex;
67
72
  flex-wrap: wrap;
68
73
  }
69
-
70
74
  </style>
package/dist/Tab.svelte CHANGED
@@ -1,23 +1,26 @@
1
- <script>import warningCircleFill from '@iconify-icons/ph/warning-circle-fill';
2
- import { derivedStore } from '@txstate-mws/svelte-store';
3
- import { getContext, setContext } from 'svelte';
4
- import { writable } from 'svelte/store';
5
- import Icon from './Icon.svelte';
6
- import { TAB_CONTEXT, TAB_NAME_CONTEXT } from './TabStore';
7
- export let name;
8
- const { store, onClick, onKeyDown, tabelements } = getContext(TAB_CONTEXT);
9
- const accordion = store.accordion();
10
- const current = store.currentName();
11
- const def = derivedStore(store, v => v.tabs.find(t => t.name === name));
12
- const title = derivedStore(def, 'title');
13
- const tabid = derivedStore(store, v => v.tabids[name]);
14
- const panelid = derivedStore(store, v => v.panelids[name]);
15
- $: active = $current === name;
16
- const idx = $store.tabs.findIndex(t => t.name === name);
17
- const last = idx === $store.tabs.length - 1;
18
- const tabNameStore = writable(name);
19
- $: $tabNameStore = name;
20
- setContext(TAB_NAME_CONTEXT, tabNameStore);
1
+ <script lang="ts">
2
+ import warningCircleFill from '@iconify-icons/ph/warning-circle-fill'
3
+ import { derivedStore } from '@txstate-mws/svelte-store'
4
+ import { getContext, setContext } from 'svelte'
5
+ import { writable } from 'svelte/store'
6
+ import Icon from './Icon.svelte'
7
+ import { type TabStore, TAB_CONTEXT, TAB_NAME_CONTEXT } from './TabStore'
8
+
9
+ export let name: string
10
+
11
+ const { store, onClick, onKeyDown, tabelements } = getContext<{ store: TabStore, onClick: (idx: number) => (() => void), onKeyDown: (idx: number) => (() => void), tabelements: HTMLElement[] }>(TAB_CONTEXT)
12
+ const accordion = store.accordion()
13
+ const current = store.currentName()
14
+ const def = derivedStore(store, v => v.tabs.find(t => t.name === name))
15
+ const title = derivedStore(def, 'title')
16
+ const tabid = derivedStore(store, v => v.tabids[name])
17
+ const panelid = derivedStore(store, v => v.panelids[name])
18
+ $: active = $current === name
19
+ const idx = $store.tabs.findIndex(t => t.name === name)
20
+ const last = idx === $store.tabs.length - 1
21
+ const tabNameStore = writable(name)
22
+ $: $tabNameStore = name
23
+ setContext(TAB_NAME_CONTEXT, tabNameStore)
21
24
  </script>
22
25
 
23
26
  {#if $store.tabs.length > 1}
@@ -77,5 +80,4 @@ setContext(TAB_NAME_CONTEXT, tabNameStore);
77
80
  margin-left: 0.4em;
78
81
  }
79
82
 
80
-
81
83
  </style>
package/dist/Tabs.svelte CHANGED
@@ -1,114 +1,116 @@
1
- <script>import caretRightFill from '@iconify-icons/ph/caret-right-fill';
2
- import warningCircleFill from '@iconify-icons/ph/warning-circle-fill';
3
- import { modifierKey, resize, offset, PopupMenu } from '@txstate-mws/svelte-components';
4
- import { Store } from '@txstate-mws/svelte-store';
5
- import { getContext, onMount, setContext, tick } from 'svelte';
6
- import { roundTo } from 'txstate-utils';
7
- import { DIALOG_TABS_CONTEXT } from './Dialog.svelte';
8
- import Icon from './Icon.svelte';
9
- import { TabStore, TAB_CONTEXT } from './TabStore';
10
- export let tabs;
11
- export let active = undefined;
12
- export let store = new TabStore(tabs, active);
13
- export let disableDialogControl = false;
14
- export let accordionOnMobile = false;
15
- /**
16
- * Takes the width of the tabs area, in pixels, and returns the number of tabs that should be
17
- * displayed at that width.
18
- */
19
- export let columnsShown = undefined;
20
- $: store.update(v => ({ ...v, tabs, accordionOnMobile }));
21
- const activeStore = new Store({});
22
- const tabelements = [];
23
- let tabOverflowButton;
24
- let activeelement;
25
- let hiddenTabs = [];
26
- setContext(TAB_CONTEXT, { store, onClick, onKeyDown, tabelements });
27
- const dialogContext = (disableDialogControl ? undefined : getContext(DIALOG_TABS_CONTEXT)) ?? { change: () => { } };
28
- dialogContext.onNext = () => { store.right(); };
29
- dialogContext.onPrev = () => { store.left(); };
30
- $: dialogContext.prevTitle = $store.prevTitle;
31
- $: dialogContext.nextTitle = $store.nextTitle;
32
- $: dialogContext.hasRequired = $store.requireNext;
33
- $: dialogContext.change($store);
34
- if (!disableDialogControl)
35
- setContext(DIALOG_TABS_CONTEXT, { change: () => { } }); // reset context so that any sub-tabs do NOT control the Dialog component
36
- const currentName = store.currentName();
37
- const currentIdx = store.currentIdx();
38
- const accordion = store.accordion();
39
- $: cols = (typeof columnsShown === 'function') ? columnsShown($store.clientWidth ?? 1024) : Math.min(Math.floor(($store.clientWidth ?? 1024) / 90), $store.tabs.length);
40
- $: scalefactor = Math.min(roundTo(($store.clientWidth ?? 1024) / (cols * 130), 4), 1);
41
- $: wrapping = cols !== $store.tabs.length;
42
- $: dialogContext.hasTabs = !$accordion;
43
- function onClick(idx) {
44
- return () => store.activate(idx);
45
- }
46
- function onKeyDown(idx) {
1
+ <script lang="ts">
2
+ import caretRightFill from '@iconify-icons/ph/caret-right-fill'
3
+ import warningCircleFill from '@iconify-icons/ph/warning-circle-fill'
4
+ import { type ElementOffsets, modifierKey, resize, offset, PopupMenu } from '@txstate-mws/svelte-components'
5
+ import { Store } from '@txstate-mws/svelte-store'
6
+ import { getContext, onMount, setContext, tick } from 'svelte'
7
+ import { roundTo } from 'txstate-utils'
8
+ import { DIALOG_TABS_CONTEXT, type DialogTabContext } from './Dialog.svelte'
9
+ import Icon from './Icon.svelte'
10
+ import { TabStore, TAB_CONTEXT, type TabDef } from './TabStore'
11
+
12
+ export let tabs: TabDef[]
13
+ export let active: string | undefined = undefined
14
+ export let store = new TabStore(tabs, active)
15
+ export let disableDialogControl = false
16
+ export let accordionOnMobile = false
17
+ /**
18
+ * Takes the width of the tabs area, in pixels, and returns the number of tabs that should be
19
+ * displayed at that width.
20
+ */
21
+ export let columnsShown: ((tabsWidth: number) => number) | undefined = undefined
22
+ $: store.update(v => ({ ...v, tabs, accordionOnMobile }))
23
+
24
+ const activeStore = new Store<ElementOffsets>({})
25
+ const tabelements: HTMLElement[] = []
26
+ let tabOverflowButton: HTMLButtonElement
27
+ let activeelement: HTMLElement
28
+ let hiddenTabs: TabDef[] = []
29
+ setContext(TAB_CONTEXT, { store, onClick, onKeyDown, tabelements })
30
+
31
+ const dialogContext = (disableDialogControl ? undefined : getContext<DialogTabContext>(DIALOG_TABS_CONTEXT)) ?? { change: () => {} }
32
+ dialogContext.onNext = () => { store.right() }
33
+ dialogContext.onPrev = () => { store.left() }
34
+ $: dialogContext.prevTitle = $store.prevTitle
35
+ $: dialogContext.nextTitle = $store.nextTitle
36
+ $: dialogContext.hasRequired = $store.requireNext
37
+ $: dialogContext.change($store)
38
+ if (!disableDialogControl) setContext(DIALOG_TABS_CONTEXT, { change: () => {} }) // reset context so that any sub-tabs do NOT control the Dialog component
39
+
40
+ const currentName = store.currentName()
41
+ const currentIdx = store.currentIdx()
42
+ const accordion = store.accordion()
43
+ $: cols = (typeof columnsShown === 'function') ? columnsShown($store.clientWidth ?? 1024) : Math.min(Math.floor(($store.clientWidth ?? 1024) / 90), $store.tabs.length)
44
+ $: scalefactor = Math.min(roundTo(($store.clientWidth ?? 1024) / (cols * 130), 4), 1)
45
+ $: wrapping = cols !== $store.tabs.length
46
+ $: dialogContext.hasTabs = !$accordion
47
+
48
+ function onClick (idx: number) {
49
+ return () => store.activate(idx)
50
+ }
51
+ function onKeyDown (idx: number) {
47
52
  return async (e) => {
48
- if (modifierKey(e))
49
- return;
50
- if (['Enter', ' ', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {
51
- e.preventDefault();
52
- e.stopPropagation();
53
- }
54
- if (e.key === 'Enter' || e.key === ' ') {
55
- store.activate(idx);
56
- }
57
- else if (e.key === 'ArrowLeft' && $store.current > 0) {
58
- store.left();
59
- await tick();
60
- tabelements[$store.current].focus();
61
- }
62
- else if (e.key === 'ArrowRight' && $store.current < $store.tabs.length - 1) {
63
- store.right();
64
- await tick();
65
- tabelements[$store.current].focus();
66
- }
67
- else if (e.key === 'Home' && $store.current > 0) {
68
- store.home();
69
- await tick();
70
- tabelements[$store.current].focus();
71
- }
72
- else if (e.key === 'End' && $store.current < $store.tabs.length - 1) {
73
- store.end();
74
- await tick();
75
- tabelements[$store.current].focus();
76
- }
77
- };
78
- }
79
- function isActive(idx, activeidx) {
80
- return idx === (activeidx ?? 0);
81
- }
82
- function onOverflowChange(e) {
83
- store.activateName(e.detail.value);
84
- }
85
- function tabIsHidden(index) {
86
- if (!wrapping)
87
- return false;
88
- const left = Math.max($currentIdx - cols + 1, 0);
89
- const right = Math.min(left + cols - 1);
53
+ if (modifierKey(e)) return
54
+ if (['Enter', ' ', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {
55
+ e.preventDefault()
56
+ e.stopPropagation()
57
+ }
58
+ if (e.key === 'Enter' || e.key === ' ') {
59
+ store.activate(idx)
60
+ } else if (e.key === 'ArrowLeft' && $store.current > 0) {
61
+ store.left()
62
+ await tick()
63
+ tabelements[$store.current].focus()
64
+ } else if (e.key === 'ArrowRight' && $store.current < $store.tabs.length - 1) {
65
+ store.right()
66
+ await tick()
67
+ tabelements[$store.current].focus()
68
+ } else if (e.key === 'Home' && $store.current > 0) {
69
+ store.home()
70
+ await tick()
71
+ tabelements[$store.current].focus()
72
+ } else if (e.key === 'End' && $store.current < $store.tabs.length - 1) {
73
+ store.end()
74
+ await tick()
75
+ tabelements[$store.current].focus()
76
+ }
77
+ }
78
+ }
79
+
80
+ function isActive (idx, activeidx) {
81
+ return idx === (activeidx ?? 0)
82
+ }
83
+
84
+ function onOverflowChange (e: any) {
85
+ store.activateName(e.detail.value)
86
+ }
87
+
88
+ function tabIsHidden (index: number) {
89
+ if (!wrapping) return false
90
+ const left = Math.max($currentIdx - cols + 1, 0)
91
+ const right = Math.min(left + cols - 1)
90
92
  // return (index !== $currentIdx && index >= cols) || (index === cols - 1 && $currentIdx > cols - 1)
91
- return (index !== $currentIdx) && ((index < left) || (index > right));
92
- }
93
- const activeOversize = 2;
94
- async function reactToCurrent(..._) {
95
- if (!activeelement)
96
- return;
97
- const tabelement = tabelements[$currentIdx];
98
- if (!tabelement)
99
- return;
100
- const span = tabelement.querySelector(':scope > span');
101
- if (!span)
102
- return;
103
- const left = span.offsetLeft - activeelement.offsetLeft - activeOversize;
104
- const width = span.offsetWidth + (activeOversize * 2);
105
- activeelement.style.transform = `translateX(${left}px)`;
106
- activeelement.style.width = `${width}px`;
107
- hiddenTabs = $store.tabs.filter((tab, idx) => { return tabIsHidden(idx); });
108
- }
109
- $: active = $currentName;
110
- $: void reactToCurrent($activeStore);
111
- onMount(reactToCurrent);
93
+ return (index !== $currentIdx) && ((index < left) || (index > right))
94
+ }
95
+
96
+ const activeOversize = 2
97
+ async function reactToCurrent (..._: any) {
98
+ if (!activeelement) return
99
+ const tabelement = tabelements[$currentIdx]
100
+ if (!tabelement) return
101
+ const span = tabelement.querySelector(':scope > span') as HTMLSpanElement
102
+ if (!span) return
103
+ const left = span.offsetLeft - activeelement.offsetLeft - activeOversize
104
+ const width = span.offsetWidth + (activeOversize * 2)
105
+ activeelement.style.transform = `translateX(${left}px)`
106
+ activeelement.style.width = `${width}px`
107
+ hiddenTabs = $store.tabs.filter((tab, idx) => { return tabIsHidden(idx) })
108
+ }
109
+
110
+ $: active = $currentName
111
+ $: void reactToCurrent($activeStore)
112
+ onMount(reactToCurrent)
113
+
112
114
  </script>
113
115
 
114
116
  {#if $store.tabs.length > 1}
@@ -208,5 +210,4 @@ onMount(reactToCurrent);
208
210
  bottom: -3px;
209
211
  border-radius: 2px;
210
212
  }
211
-
212
213
  </style>
@@ -1,9 +1,10 @@
1
- <script>export let tip = undefined;
2
- export let top = false;
3
- export let right = false;
4
- export let bottom = false;
5
- export let left = false;
6
- export let active = false;
1
+ <script lang="ts">
2
+ export let tip: string | undefined = undefined
3
+ export let top: boolean = false
4
+ export let right: boolean = false
5
+ export let bottom: boolean = false
6
+ export let left: boolean = false
7
+ export let active: boolean = false
7
8
  </script>
8
9
 
9
10
  <style>
@@ -35,7 +36,6 @@ export let active = false;
35
36
  border: 1px solid #000;
36
37
  background-color: #fff;
37
38
  }
38
-
39
39
  </style>
40
40
 
41
41
  {#if tip}