antd-solid 0.0.2 → 0.0.3

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 (105) hide show
  1. package/.eslintignore +2 -0
  2. package/.husky/pre-commit +4 -0
  3. package/.vscode/settings.json +1 -1
  4. package/docs/.vitepress/components/Code.vue +127 -11
  5. package/docs/.vitepress/config.ts +39 -1
  6. package/docs/.vitepress/theme/index.css +4 -0
  7. package/docs/.vitepress/theme/index.ts +0 -1
  8. package/docs/components/{Button.tsx → button/Base.tsx} +1 -0
  9. package/docs/components/button/Danger.tsx +21 -0
  10. package/docs/components/button.md +19 -7
  11. package/docs/components/collapse/Base.tsx +25 -0
  12. package/docs/components/collapse.md +26 -0
  13. package/docs/components/color-picker/Base.tsx +14 -0
  14. package/docs/components/color-picker.md +26 -0
  15. package/docs/components/compact/Base.tsx +27 -0
  16. package/docs/components/compact.md +26 -0
  17. package/docs/components/date-picker/Base.tsx +15 -0
  18. package/docs/components/date-picker.md +26 -0
  19. package/docs/components/empty/Base.tsx +8 -0
  20. package/docs/components/empty/PRESENTED_IMAGE_SIMPLE.tsx +8 -0
  21. package/docs/components/empty.md +32 -0
  22. package/docs/components/form/Base.tsx +63 -0
  23. package/docs/components/form.md +27 -0
  24. package/docs/components/image/Base.tsx +13 -0
  25. package/docs/components/image.md +26 -0
  26. package/docs/components/input/AddonBeforeAndAfter.tsx +14 -0
  27. package/docs/components/input/Base.tsx +15 -0
  28. package/docs/components/input/Disabled.tsx +19 -0
  29. package/docs/components/input/PrefixAndSuffix.tsx +14 -0
  30. package/docs/components/input/Status.tsx +25 -0
  31. package/docs/components/input/TextArea.tsx +14 -0
  32. package/docs/components/input-number/Base.tsx +15 -0
  33. package/docs/components/input-number/MinMax.tsx +17 -0
  34. package/docs/components/input-number.md +34 -0
  35. package/docs/components/input.md +57 -0
  36. package/docs/components/modal/Base.tsx +35 -0
  37. package/docs/components/modal.md +26 -0
  38. package/docs/components/popconfirm/Base.tsx +25 -0
  39. package/docs/components/popconfirm.md +26 -0
  40. package/docs/components/popover/Base.tsx +19 -0
  41. package/docs/components/popover.md +26 -0
  42. package/docs/components/progress/Base.tsx +16 -0
  43. package/docs/components/progress.md +26 -0
  44. package/docs/components/radio/Base.tsx +10 -0
  45. package/docs/components/radio.md +26 -0
  46. package/docs/components/segmented/Base.tsx +10 -0
  47. package/docs/components/segmented/Block.tsx +10 -0
  48. package/docs/components/segmented/Disabled.tsx +28 -0
  49. package/docs/components/segmented.md +38 -0
  50. package/docs/components/select/AllowClear.tsx +18 -0
  51. package/docs/components/select/Base.tsx +17 -0
  52. package/docs/components/select.md +35 -0
  53. package/docs/components/switch/Base.tsx +14 -0
  54. package/docs/components/switch.md +26 -0
  55. package/docs/components/{Table.tsx → table/Base.tsx} +2 -2
  56. package/docs/components/table.md +12 -6
  57. package/docs/components/tabs/Base.tsx +25 -0
  58. package/docs/components/tabs/Segment.tsx +25 -0
  59. package/docs/components/tabs.md +33 -0
  60. package/docs/components/tooltip/Base.tsx +12 -0
  61. package/docs/components/tooltip/Placement.tsx +90 -0
  62. package/docs/components/tooltip.md +32 -0
  63. package/docs/components/tree/Base.tsx +45 -0
  64. package/docs/components/tree.md +26 -0
  65. package/global.d.ts +9 -0
  66. package/package.json +29 -14
  67. package/patches/vitepress@1.0.0-rc.4.patch +60 -0
  68. package/rollup.config.js +60 -20
  69. package/scripts/annotationNonProductionCode.js +30 -0
  70. package/scripts/cancelAnnotationNonProductionCode.js +30 -0
  71. package/src/Button.tsx +51 -12
  72. package/src/Collapse/index.tsx +86 -0
  73. package/src/ColorPicker.tsx +6 -61
  74. package/src/Compact.tsx +15 -0
  75. package/src/Empty/PRESENTED_IMAGE_SIMPLE.tsx +15 -0
  76. package/src/Empty/assets/EmptySvg.tsx +43 -0
  77. package/src/Empty/assets/SimpleEmptySvg.tsx +16 -0
  78. package/src/Empty/index.tsx +20 -0
  79. package/src/Input.tsx +154 -62
  80. package/src/InputNumber.tsx +68 -62
  81. package/src/Modal.tsx +90 -62
  82. package/src/Popconfirm.tsx +5 -3
  83. package/src/Segmented/index.tsx +95 -0
  84. package/src/Select.tsx +125 -3
  85. package/src/Switch.tsx +1 -1
  86. package/src/Table.tsx +36 -29
  87. package/src/Tabs.tsx +88 -45
  88. package/src/Tooltip.tsx +233 -87
  89. package/src/Tree.tsx +4 -4
  90. package/src/form/Form.tsx +94 -0
  91. package/src/form/FormItem.tsx +139 -0
  92. package/src/form/context.ts +16 -0
  93. package/src/form/index.ts +13 -0
  94. package/src/hooks/createControllableValue.ts +9 -6
  95. package/src/index.ts +12 -5
  96. package/src/types/index.ts +5 -0
  97. package/src/utils/EventEmitter.ts +15 -0
  98. package/src/utils/component.tsx +1 -1
  99. package/src/utils/solid.ts +8 -3
  100. package/src/utils/zh_CN.ts +236 -0
  101. package/tsconfig.json +6 -4
  102. package/unocss.config.ts +90 -6
  103. package/src/Button.css +0 -14
  104. package/src/Form.tsx +0 -98
  105. package/src/index.css +0 -21
package/src/Table.tsx CHANGED
@@ -1,45 +1,52 @@
1
- import { type JSXElement, For } from 'solid-js'
1
+ import Empty from './Empty'
2
+ import { type JSXElement, For, Show } from 'solid-js'
2
3
 
3
- export interface Column<R extends {}> {
4
+ export interface TableColumn<R extends {}> {
4
5
  title: JSXElement
5
6
  render: (row: R) => JSXElement
6
7
  }
7
8
 
8
9
  export interface TableProps<R extends {}> {
9
- columns: Array<Column<R>>
10
+ columns: Array<TableColumn<R>>
10
11
  dataSource: R[]
11
12
  }
12
13
 
13
14
  const Table = <R extends {}>(props: TableProps<R>) => {
14
15
  return (
15
- <table class="ant-w-full">
16
- <thead>
17
- <tr>
18
- <For each={props.columns}>
19
- {item => (
20
- <th class="ant-p-16px ant-bg-[var(--light-bg-color)] ant-font-bold ant-[border-bottom:1px_solid_var(--secondary-border-color)] ant-text-left">
21
- {item.title}
22
- </th>
16
+ <div>
17
+ <table class="ant-w-full">
18
+ <thead>
19
+ <tr>
20
+ <For each={props.columns}>
21
+ {item => (
22
+ <th class="ant-p-16px ant-bg-[var(--light-bg-color)] ant-font-bold ant-[border-bottom:1px_solid_var(--secondary-border-color)] ant-text-left">
23
+ {item.title}
24
+ </th>
25
+ )}
26
+ </For>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ <For each={props.dataSource}>
31
+ {row => (
32
+ <tr class="hover:ant-bg-[var(--light-bg-color)]">
33
+ <For each={props.columns}>
34
+ {item => (
35
+ <td class="ant-p-16px ant-[border-bottom:1px_solid_var(--secondary-border-color)]">
36
+ {item.render(row)}
37
+ </td>
38
+ )}
39
+ </For>
40
+ </tr>
23
41
  )}
24
42
  </For>
25
- </tr>
26
- </thead>
27
- <tbody>
28
- <For each={props.dataSource}>
29
- {row => (
30
- <tr class="hover:ant-bg-[var(--light-bg-color)]">
31
- <For each={props.columns}>
32
- {item => (
33
- <td class="ant-p-16px ant-[border-bottom:1px_solid_var(--secondary-border-color)]">
34
- {item.render(row)}
35
- </td>
36
- )}
37
- </For>
38
- </tr>
39
- )}
40
- </For>
41
- </tbody>
42
- </table>
43
+ </tbody>
44
+ </table>
45
+
46
+ <Show when={!props.dataSource.length}>
47
+ <Empty.PRESENTED_IMAGE_SIMPLE />
48
+ </Show>
49
+ </div>
43
50
  )
44
51
  }
45
52
 
package/src/Tabs.tsx CHANGED
@@ -1,86 +1,129 @@
1
1
  import {
2
2
  type Component,
3
3
  For,
4
- type JSXElement,
5
4
  createSelector,
6
5
  createSignal,
7
6
  onMount,
8
7
  untrack,
9
8
  type JSX,
10
- Show,
9
+ onCleanup,
10
+ mergeProps,
11
+ Switch,
12
+ Match,
11
13
  } from 'solid-js'
12
14
  import cs from 'classnames'
13
- import { isNil } from 'lodash-es'
15
+ import Segmented from './Segmented'
16
+ import { type StringOrJSXElement } from './types'
17
+ import { unwrapStringOrJSXElement } from './utils/solid'
14
18
 
15
19
  export interface Tab {
16
20
  key: string
17
- label: JSXElement
18
- children?: JSXElement
21
+ label: StringOrJSXElement
22
+ children?: StringOrJSXElement
19
23
  }
20
24
 
21
25
  export interface TabsProps {
26
+ type?: 'line' | 'segment'
22
27
  class?: string
23
- navWrapClass?: string
28
+ navClass?: string
24
29
  navItemClass?: string
30
+ contentClass?: string
25
31
  items: Tab[]
26
32
  }
27
33
 
28
- const Tabs: Component<TabsProps> = props => {
29
- const [selectedItem, setSelectedItem] = createSignal<Tab | undefined>(untrack(() => props.items[0]))
34
+ const Tabs: Component<TabsProps> = _props => {
35
+ const props = mergeProps(
36
+ {
37
+ type: 'line',
38
+ } as TabsProps,
39
+ _props,
40
+ )
41
+
42
+ const [selectedItem, setSelectedItem] = createSignal<Tab | undefined>(
43
+ untrack(() => props.items[0]),
44
+ )
30
45
  const isSelectedItem = createSelector(() => selectedItem()?.key)
31
46
  const [selectedBarStyle, setSelectedBarStyle] = createSignal<JSX.CSSProperties>({
32
47
  left: '0px',
33
48
  width: '0px',
34
49
  })
35
- const updateSelectedBarStyle = (el: HTMLElement) => {
50
+
51
+ let nav: HTMLDivElement | undefined
52
+ const updateSelectedBarStyle = () => {
53
+ if (!nav) return
54
+
55
+ const el = nav.querySelector<HTMLElement>(':scope > .selected')
56
+ if (!el) return
57
+
36
58
  setSelectedBarStyle({
37
59
  left: `${el.offsetLeft}px`,
38
60
  width: `${el.clientWidth}px`,
39
61
  })
40
62
  }
41
-
42
- let navWrap: HTMLDivElement
43
63
  onMount(() => {
44
- updateSelectedBarStyle(navWrap.children[0] as HTMLElement)
64
+ if (!nav) return
65
+
66
+ updateSelectedBarStyle()
67
+
68
+ const resizeObserver = new ResizeObserver(() => {
69
+ updateSelectedBarStyle()
70
+ })
71
+
72
+ resizeObserver.observe(nav)
73
+ onCleanup(() => {
74
+ resizeObserver.disconnect()
75
+ })
45
76
  })
46
77
 
47
78
  return (
48
- <div class={cs(props.class, 'ant-grid ant-[grid-template-rows:auto_1fr]')}>
49
- <div
50
- ref={navWrap!}
51
- class={cs(
52
- 'ant-flex ant-gap-32px ant-[border-bottom:solid_1px_rgba(5,5,5,0.1)] ant-relative',
53
- props.navWrapClass,
54
- )}
55
- >
56
- <For each={props.items}>
57
- {item => (
58
- <div
59
- class={cs(
60
- 'ant-py-12px ant-cursor-pointer',
61
- props.navItemClass,
62
- isSelectedItem(item.key) && 'ant-text-[var(--primary-color)]',
79
+ <div class={props.class}>
80
+ <Switch>
81
+ <Match when={props.type === 'line'}>
82
+ <div
83
+ ref={nav!}
84
+ class={cs(
85
+ 'ant-mb-16px ant-flex ant-gap-32px ant-[border-bottom:solid_1px_rgba(5,5,5,0.1)] ant-relative',
86
+ props.navClass,
87
+ )}
88
+ >
89
+ <For each={props.items}>
90
+ {item => (
91
+ <div
92
+ class={cs(
93
+ 'ant-py-12px ant-cursor-pointer',
94
+ props.navItemClass,
95
+ isSelectedItem(item.key) && 'ant-text-[var(--primary-color)] selected',
96
+ )}
97
+ onClick={() => {
98
+ setSelectedItem(item)
99
+ updateSelectedBarStyle()
100
+ }}
101
+ >
102
+ {unwrapStringOrJSXElement(item.label)}
103
+ </div>
63
104
  )}
64
- onClick={e => {
65
- setSelectedItem(item)
66
- updateSelectedBarStyle(e.currentTarget)
67
- }}
68
- >
69
- {item.label}
70
- </div>
71
- )}
72
- </For>
105
+ </For>
73
106
 
74
- <div
75
- role={'selected-bar' as any}
76
- class="ant-absolute ant-bottom-0 ant-bg-[var(--primary-color)] ant-h-2px ant-transition-left"
77
- style={selectedBarStyle()}
78
- />
79
- </div>
107
+ <div
108
+ role={'selected-bar' as any}
109
+ class="ant-absolute ant-bottom-0 ant-bg-[var(--primary-color)] ant-h-2px ant-transition-left"
110
+ style={selectedBarStyle()}
111
+ />
112
+ </div>
113
+ </Match>
114
+ <Match when={props.type === 'segment'}>
115
+ <Segmented
116
+ block
117
+ options={props.items.map(item => ({
118
+ label: item.label,
119
+ value: item.key,
120
+ onClick: () => setSelectedItem(item),
121
+ }))}
122
+ />
123
+ </Match>
124
+ </Switch>
80
125
 
81
- <Show when={!isNil(selectedItem()?.children)}>
82
- <div class="ant-px-12px ant-py-16px ant-overflow-auto">{selectedItem()?.children}</div>
83
- </Show>
126
+ <div class={props.contentClass}>{unwrapStringOrJSXElement(selectedItem()?.children)}</div>
84
127
  </div>
85
128
  )
86
129
  }
package/src/Tooltip.tsx CHANGED
@@ -2,17 +2,20 @@ import { compact } from 'lodash-es'
2
2
  import {
3
3
  type Component,
4
4
  type JSXElement,
5
+ type JSX,
5
6
  children,
6
7
  createEffect,
7
8
  Show,
8
9
  mergeProps,
9
10
  onCleanup,
10
11
  createMemo,
12
+ createSignal,
11
13
  } from 'solid-js'
12
14
  import { Portal } from 'solid-js/web'
13
15
  import cs from 'classnames'
14
16
  import createControllableValue from './hooks/createControllableValue'
15
17
  import { useClickAway } from './hooks'
18
+ import { toArray } from './utils/array'
16
19
 
17
20
  type ActionType = 'hover' | 'focus' | 'click' | 'contextMenu'
18
21
  type TooltipPlacement =
@@ -33,11 +36,12 @@ export interface TooltipProps {
33
36
  /**
34
37
  * 默认: hover
35
38
  */
36
- trigger?: ActionType
39
+ trigger?: ActionType | ActionType[]
37
40
  /**
38
41
  * 默认: top
39
42
  */
40
43
  placement?: TooltipPlacement
44
+ contentStyle?: JSX.CSSProperties
41
45
  content?: JSXElement | ((close: () => void) => JSXElement)
42
46
  children?: JSXElement
43
47
  open?: boolean
@@ -70,13 +74,12 @@ const Tooltip: Component<TooltipProps> = _props => {
70
74
  placement: 'top',
71
75
  mode: 'dark',
72
76
  arrow: true,
73
- } as TooltipProps,
77
+ },
74
78
  _props,
75
79
  )
76
80
 
77
81
  const resolvedChildren = children(() => _props.children)
78
- let contentWrap: HTMLDivElement
79
- let arrow: HTMLDivElement
82
+ let content: HTMLDivElement
80
83
  const [open, setOpen] = createControllableValue(_props, {
81
84
  defaultValue: false,
82
85
  valuePropName: 'open',
@@ -86,117 +89,260 @@ const Tooltip: Component<TooltipProps> = _props => {
86
89
 
87
90
  createEffect(() => {
88
91
  const _children = resolvedChildren() as Element
89
- switch (props.trigger) {
90
- case 'hover':
91
- _children.addEventListener('mouseenter', reverseOpen)
92
- onCleanup(() => {
93
- _children.removeEventListener('mouseenter', reverseOpen)
94
- })
95
-
96
- _children.addEventListener('mouseleave', reverseOpen)
97
- onCleanup(() => {
98
- _children.removeEventListener('mouseleave', reverseOpen)
99
- })
100
- break
101
- case 'click':
102
- _children.addEventListener('click', reverseOpen)
103
- onCleanup(() => {
104
- _children.removeEventListener('click', reverseOpen)
105
- })
92
+ toArray(props.trigger).forEach(trigger => {
93
+ switch (trigger) {
94
+ case 'hover':
95
+ _children.addEventListener('mouseenter', reverseOpen)
96
+ _children.addEventListener('mouseleave', reverseOpen)
97
+ onCleanup(() => {
98
+ _children.removeEventListener('mouseenter', reverseOpen)
99
+ _children.removeEventListener('mouseleave', reverseOpen)
100
+ })
101
+ break
102
+ case 'click':
103
+ _children.addEventListener('click', reverseOpen)
104
+ onCleanup(() => {
105
+ _children.removeEventListener('click', reverseOpen)
106
+ })
106
107
 
107
- useClickAway(
108
- () => setOpen(false),
109
- () => compact([contentWrap, _children]),
110
- )
111
- break
112
- }
108
+ useClickAway(
109
+ () => setOpen(false),
110
+ () => compact([content, _children]),
111
+ )
112
+ break
113
+ case 'focus':
114
+ _children.addEventListener('focus', reverseOpen)
115
+ _children.addEventListener('blur', reverseOpen)
116
+ onCleanup(() => {
117
+ _children.removeEventListener('focus', reverseOpen)
118
+ _children.removeEventListener('blur', reverseOpen)
119
+ })
120
+ break
121
+ }
122
+ })
113
123
  })
114
124
 
125
+ const [childrenRect, setChildrenRect] = createSignal(new DOMRect())
115
126
  createEffect(() => {
116
127
  if (open()) {
117
128
  const _children = resolvedChildren() as Element
118
- const childrenRect = _children.getBoundingClientRect()
119
- const pointAtCenter = typeof props.arrow === 'object' ? props.arrow.pointAtCenter : false
120
- const arrowOffset = 8
121
-
122
- switch (props.placement) {
123
- case 'top':
124
- contentWrap.style.top = `${childrenRect.top}px`
125
- contentWrap.style.left = `${childrenRect.left + childrenRect.width / 2}px`
126
- contentWrap.style.transform = 'translate(-50%, -100%)'
127
- break
128
- case 'topRight':
129
- contentWrap.style.top = `${childrenRect.top}px`
130
- contentWrap.style.left = `${childrenRect.right}px`
131
- contentWrap.style.transform = 'translate(-100%, -100%)'
132
- if (arrow) arrow.style.right = `${arrowOffset}px`
133
- break
134
- case 'bottom':
135
- contentWrap.style.top = `${childrenRect.top + childrenRect.height}px`
136
- contentWrap.style.left = `${childrenRect.left + childrenRect.width / 2}px`
137
- contentWrap.style.transform = 'translate(-50%, 0)'
138
- break
139
- case 'bottomLeft':
140
- contentWrap.style.top = `${childrenRect.top + childrenRect.height}px`
141
- contentWrap.style.left = `${childrenRect.left}px`
142
- if (arrow) arrow.style.left = `${arrowOffset}px`
143
- break
144
- case 'bottomRight':
145
- contentWrap.style.top = `${childrenRect.top + childrenRect.height}px`
146
- contentWrap.style.left = `${childrenRect.right + (pointAtCenter ? arrowOffset : 0)}px`
147
- contentWrap.style.transform = 'translate(-100%, 0)'
148
- if (arrow) arrow.style.right = `${arrowOffset}px`
149
- break
150
- }
129
+ setChildrenRect(_children.getBoundingClientRect())
151
130
  }
152
131
  })
153
132
 
154
- const direction = createMemo(() => {
155
- if (props.placement?.startsWith('top')) return 'top'
156
- if (props.placement?.startsWith('bottom')) return 'bottom'
157
- if (props.placement?.startsWith('left')) return 'left'
158
- if (props.placement?.startsWith('right')) return 'right'
133
+ const firstDirection = createMemo(() => {
134
+ if (props.placement.startsWith('bottom')) return 'bottom'
135
+ if (props.placement.startsWith('left')) return 'left'
136
+ if (props.placement.startsWith('right')) return 'right'
137
+ return 'top'
138
+ })
139
+
140
+ const secondDirection = createMemo(() => {
141
+ if (props.placement.endsWith('Left')) return 'left'
142
+ if (props.placement.endsWith('Right')) return 'right'
143
+ if (props.placement.endsWith('Top')) return 'top'
144
+ if (props.placement.endsWith('Bottom')) return 'bottom'
145
+ return 'center'
146
+ })
147
+
148
+ const arrowOffset = createMemo(() => (props.arrow ? 8 : 0))
149
+ const contentPositionStyle = createMemo(() => {
150
+ switch (props.placement) {
151
+ case 'top':
152
+ return {
153
+ top: `${childrenRect().top - arrowOffset()}px`,
154
+ left: `${childrenRect().left + childrenRect().width / 2}px`,
155
+ transform: 'translate(-50%, -100%)',
156
+ } as JSX.CSSProperties
157
+ case 'topLeft':
158
+ return {
159
+ top: `${childrenRect().top - arrowOffset()}px`,
160
+ left: `${childrenRect().left}px`,
161
+ transform: 'translate(0, -100%)',
162
+ } as JSX.CSSProperties
163
+ case 'topRight':
164
+ return {
165
+ top: `${childrenRect().top - arrowOffset()}px`,
166
+ left: `${childrenRect().right}px`,
167
+ transform: 'translate(-100%, -100%)',
168
+ } as JSX.CSSProperties
169
+ case 'bottom':
170
+ return {
171
+ top: `${childrenRect().bottom + arrowOffset()}px`,
172
+ left: `${childrenRect().left + childrenRect().width / 2}px`,
173
+ transform: 'translate(-50%, 0)',
174
+ } as JSX.CSSProperties
175
+ case 'bottomLeft':
176
+ return {
177
+ top: `${childrenRect().bottom + arrowOffset()}px`,
178
+ left: `${childrenRect().left}px`,
179
+ } as JSX.CSSProperties
180
+ case 'bottomRight':
181
+ return {
182
+ top: `${childrenRect().bottom + arrowOffset()}px`,
183
+ left: `${childrenRect().right}px`,
184
+ transform: 'translate(-100%, 0)',
185
+ } as JSX.CSSProperties
186
+ case 'left':
187
+ return {
188
+ top: `${childrenRect().top + childrenRect().height / 2}px`,
189
+ left: `${childrenRect().left - arrowOffset()}px`,
190
+ transform: 'translate(-100%, -50%)',
191
+ } as JSX.CSSProperties
192
+ case 'leftTop':
193
+ return {
194
+ top: `${childrenRect().top}px`,
195
+ left: `${childrenRect().left - arrowOffset()}px`,
196
+ transform: 'translate(-100%)',
197
+ } as JSX.CSSProperties
198
+ case 'leftBottom':
199
+ return {
200
+ top: `${childrenRect().bottom}px`,
201
+ left: `${childrenRect().left - arrowOffset()}px`,
202
+ transform: 'translate(-100%, -100%)',
203
+ } as JSX.CSSProperties
204
+ case 'right':
205
+ return {
206
+ top: `${childrenRect().top + childrenRect().height / 2}px`,
207
+ left: `${childrenRect().right + arrowOffset()}px`,
208
+ transform: 'translate(0, -50%)',
209
+ } as JSX.CSSProperties
210
+ case 'rightTop':
211
+ return {
212
+ top: `${childrenRect().top}px`,
213
+ left: `${childrenRect().right + arrowOffset()}px`,
214
+ } as JSX.CSSProperties
215
+ case 'rightBottom':
216
+ return {
217
+ top: `${childrenRect().bottom}px`,
218
+ left: `${childrenRect().right + arrowOffset()}px`,
219
+ transform: 'translate(0, -100%)',
220
+ } as JSX.CSSProperties
221
+ }
222
+ })
223
+ const arrowStyle = createMemo(() => {
224
+ switch (props.placement) {
225
+ case 'top':
226
+ return {
227
+ 'border-top-color': 'var(--color)',
228
+ top: '100%',
229
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
230
+ left: '50%',
231
+ transform: 'translateX(-50%)',
232
+ } as JSX.CSSProperties
233
+ case 'topLeft':
234
+ return {
235
+ 'border-top-color': 'var(--color)',
236
+ top: '100%',
237
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
238
+ left: '8px',
239
+ } as JSX.CSSProperties
240
+ case 'topRight':
241
+ return {
242
+ 'border-top-color': 'var(--color)',
243
+ top: '100%',
244
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
245
+ right: '8px',
246
+ } as JSX.CSSProperties
247
+ case 'bottom':
248
+ return {
249
+ 'border-bottom-color': 'var(--color)',
250
+ bottom: '100%',
251
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
252
+ left: '50%',
253
+ transform: 'translateX(-50%)',
254
+ } as JSX.CSSProperties
255
+ case 'bottomLeft':
256
+ return {
257
+ 'border-bottom-color': 'var(--color)',
258
+ bottom: '100%',
259
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
260
+ left: '8px',
261
+ } as JSX.CSSProperties
262
+ case 'bottomRight':
263
+ return {
264
+ 'border-bottom-color': 'var(--color)',
265
+ bottom: '100%',
266
+ filter: 'drop-shadow(3px 2px 2px rgba(0, 0, 0, 0.08))',
267
+ right: '8px',
268
+ } as JSX.CSSProperties
269
+ case 'left':
270
+ return {
271
+ 'border-left-color': 'var(--color)',
272
+ top: '50%',
273
+ right: 0,
274
+ transform: 'translate(100%, -50%)',
275
+ } as JSX.CSSProperties
276
+ case 'leftTop':
277
+ return {
278
+ 'border-left-color': 'var(--color)',
279
+ top: '8px',
280
+ right: 0,
281
+ transform: 'translate(100%, 0)',
282
+ } as JSX.CSSProperties
283
+ case 'leftBottom':
284
+ return {
285
+ 'border-left-color': 'var(--color)',
286
+ bottom: '8px',
287
+ right: 0,
288
+ transform: 'translate(100%, 0)',
289
+ } as JSX.CSSProperties
290
+ case 'right':
291
+ return {
292
+ 'border-right-color': 'var(--color)',
293
+ top: '50%',
294
+ left: 0,
295
+ transform: 'translate(-100%, -50%)',
296
+ } as JSX.CSSProperties
297
+ case 'rightTop':
298
+ return {
299
+ 'border-right-color': 'var(--color)',
300
+ top: '8px',
301
+ left: 0,
302
+ transform: 'translate(-100%, 0)',
303
+ } as JSX.CSSProperties
304
+ case 'rightBottom':
305
+ return {
306
+ 'border-right-color': 'var(--color)',
307
+ bottom: '8px',
308
+ left: 0,
309
+ transform: 'translate(-100%, 0)',
310
+ } as JSX.CSSProperties
311
+ }
159
312
  })
160
313
 
161
314
  return (
162
315
  <>
163
- {resolvedChildren}
316
+ {resolvedChildren()}
164
317
 
165
318
  <Show when={open()}>
166
319
  <Portal>
167
320
  {/* Portal 存在缺陷,onClick 依然会沿着 solid 的组件树向上传播,因此需要 stopPropagation */}
168
321
  <div
169
- ref={contentWrap!}
322
+ ref={content!}
170
323
  class={cs(
171
- 'ant-z-1000 ant-fixed after:ant-content-empty',
172
- props.arrow ? '[--padding:8px]' : '[--padding:4px]',
173
- direction() === 'top' && 'ant-pb-[var(--padding)]',
174
- direction() === 'bottom' && 'ant-pt-[var(--padding)]',
324
+ 'ant-z-1000 ant-fixed ant-absolute ant-px-8px ant-py-6px ant-rounded-8px ant-box-content ant-[box-shadow:0_6px_16px_0_rgba(0,0,0,0.08),0_3px_6px_-4px_rgba(0,0,0,0.12),0_9px_28px_8px_rgba(0,0,0,0.05)]',
325
+ props.mode === 'dark' ? 'ant-bg-[rgba(0,0,0,0.85)] ant-text-white' : 'ant-bg-white',
175
326
  )}
327
+ style={{
328
+ ...contentPositionStyle(),
329
+ ...props.contentStyle,
330
+ }}
176
331
  onClick={e => {
177
332
  e.stopPropagation()
178
333
  }}
179
334
  >
180
- <div
181
- class={cs(
182
- 'ant-p-12px ant-rounded-8px ant-[box-shadow:0_6px_16px_0_rgba(0,0,0,0.08),0_3px_6px_-4px_rgba(0,0,0,0.12),0_9px_28px_8px_rgba(0,0,0,0.05)]',
183
- props.mode === 'dark' ? 'ant-bg-[rgba(0,0,0,0.85)] ant-text-white' : 'ant-bg-white',
184
- )}
185
- >
186
- <Content content={props.content} close={() => setOpen(false)} />
187
- </div>
335
+ <Content content={props.content} close={() => setOpen(false)} />
336
+
188
337
  <Show when={props.arrow}>
189
338
  <div
190
- ref={arrow!}
191
339
  class={cs(
192
- 'ant-w-8px ant-h-8px ant-rotate-45 ant-absolute',
193
- props.mode === 'dark' ? 'ant-bg-[rgba(0,0,0,0.85)]' : 'ant-bg-white',
194
- direction() === 'top' &&
195
- 'ant-bottom-0 -ant-translate-x-1/2 -ant-translate-y-1/2 ant-[filter:drop-shadow(3px_2px_2px_rgba(0,0,0,0.08))]',
196
- direction() === 'bottom' &&
197
- 'ant-top-0 -ant-translate-x-1/2 ant-translate-y-1/2 ant-[filter:drop-shadow(-3px_-2px_2px_rgba(0,0,0,0.08))]',
198
- (props.placement === 'top' || props.placement === 'bottom') && 'left-1/2',
340
+ 'ant-w-8px ant-h-8px ant-absolute ant-border-solid ant-border-4px ant-border-transparent',
199
341
  )}
342
+ style={{
343
+ '--color': props.mode === 'dark' ? 'rgba(0,0,0,0.85)' : 'white',
344
+ ...arrowStyle(),
345
+ }}
200
346
  />
201
347
  </Show>
202
348
  </div>
package/src/Tree.tsx CHANGED
@@ -166,7 +166,7 @@ function SingleLevelTree<T extends {} = {}>(props: SingleLevelTreeProps<T>) {
166
166
  </div>
167
167
  <div
168
168
  class={cs(
169
- 'ant-h-full ant-leading-24px ant-hover:bg-[rgba(0,0,0,.04)] ant-rounded-1 ant-px-1 ant-cursor-pointer ant-relative',
169
+ 'ant-h-full ant-leading-24px hover:ant-bg-[var(--hover-bg-color)] ant-rounded-1 ant-px-1 ant-cursor-pointer ant-relative',
170
170
  props.blockNode && 'w-full',
171
171
  selectedNodes()?.includes(item()) && '!ant-bg-[var(--active-bg-color)]',
172
172
  isTarget(item()) &&
@@ -215,14 +215,14 @@ function Tree<T extends {} = {}>(props: TreeProps<T>) {
215
215
  <TreeContext.Provider
216
216
  value={{
217
217
  selectedNodes,
218
- setSelectedNodes,
218
+ setSelectedNodes: setSelectedNodes as unknown as Setter<Array<{}>>,
219
219
  draggableNode,
220
- setDraggableNode,
220
+ setDraggableNode: setDraggableNode as unknown as Setter<{} | null>,
221
221
  draggableIndexes,
222
222
  setDraggableIndexes,
223
223
  isDraggable,
224
224
  targetNode,
225
- setTargetNode,
225
+ setTargetNode: setTargetNode as unknown as Setter<{} | null>,
226
226
  targetIndexes,
227
227
  setTargetIndexes,
228
228
  isTarget,