playbook_ui 16.8.0.pre.alpha.PLAY3001updateviewcomponent16599 → 16.8.0.pre.alpha.tablewidths16466
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_card/_card.tsx +1 -1
- data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
- data/app/pb_kits/playbook/pb_currency/_currency.tsx +6 -9
- data/app/pb_kits/playbook/pb_currency/currency.rb +10 -5
- data/app/pb_kits/playbook/pb_currency/currency.test.js +1 -44
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +0 -19
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +0 -2
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_react.md +0 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.md +0 -2
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_react.md +1 -3
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.md +1 -3
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_react.md +1 -3
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +0 -16
- data/app/pb_kits/playbook/pb_draggable/draggable_container.html.erb +1 -3
- data/app/pb_kits/playbook/pb_draggable/draggable_item.html.erb +0 -1
- data/app/pb_kits/playbook/pb_draggable/index.js +7 -149
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +0 -1
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +1 -67
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.html.erb +1 -0
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.jsx +21 -0
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.md +7 -0
- data/app/pb_kits/playbook/pb_icon/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_icon/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +1 -4
- data/app/pb_kits/playbook/pb_list/item.html.erb +1 -1
- data/app/pb_kits/playbook/pb_pagination/pagination.html.erb +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +1 -1
- data/app/pb_kits/playbook/pb_user_badge/user_badge.rb +6 -2
- data/dist/chunks/{_typeahead-DA__Kgp5.js → _typeahead-D2TWdJTn.js} +1 -1
- data/dist/chunks/vendor.js +2 -2
- data/dist/menu.yml +127 -67
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/engine.rb +2 -0
- data/lib/playbook/kit_base.rb +2 -2
- data/lib/playbook/pb_kit_helper.rb +5 -1
- data/lib/playbook/version.rb +1 -1
- metadata +11 -10
- data/app/pb_kits/playbook/pb_draggable/touchDrag.test.js +0 -38
- data/app/pb_kits/playbook/pb_draggable/utilities/touchDrag.ts +0 -173
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f46fd7de41487efa37647c36cc3d1d55e2260ccda34ff0f094dc4f3c21608c4
|
|
4
|
+
data.tar.gz: 60e1b0388423c2a75088ba9210b0e9456c27fb7a7b5822b5753f1c46f1abfa53
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 236bb6ec1f254c88d37bfa99aa2bb530aba234550a5635bfd19c9bb76fe0240bf818ccd4f2b859424662c2e15d1f31cae47d0831e172a9c2926e1eaa4cf3ade7
|
|
7
|
+
data.tar.gz: 63776f5d3b77b41da7a95ad4d67e89d244a0981fb8cc2220c3fc8996f5506eb2b4f94cf30989d848afc83d2104dbe17092e00851e4b4cd46ebd5a63985ddb543
|
|
@@ -162,7 +162,7 @@ const Card = (props: CardPropTypes): React.ReactElement => {
|
|
|
162
162
|
{
|
|
163
163
|
dragHandle ? (
|
|
164
164
|
<Flex>
|
|
165
|
-
<span className="card_draggable_handle
|
|
165
|
+
<span className="card_draggable_handle">
|
|
166
166
|
<Icon
|
|
167
167
|
icon="grip-dots-vertical"
|
|
168
168
|
paddingRight="xs"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% if object.draggable_item %>
|
|
5
5
|
<%= pb_rails("flex", props: { align: "center" }) do %>
|
|
6
6
|
<% if object.drag_handle %>
|
|
7
|
-
<span
|
|
7
|
+
<span classname="card_draggable_handle">
|
|
8
8
|
<%= pb_rails("icon", props: { icon: "grip-dots-vertical", padding_right: "xs" }) %>
|
|
9
9
|
</span>
|
|
10
10
|
<% end %>
|
|
@@ -59,13 +59,12 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
59
59
|
commaSeparator = false,
|
|
60
60
|
} = props
|
|
61
61
|
|
|
62
|
-
const isAmountEmpty = (value: string | number): boolean => (
|
|
63
|
-
value === '' || value == null || (typeof value === 'string' && value.trim() === '')
|
|
64
|
-
)
|
|
65
|
-
|
|
66
62
|
// Convert numeric input to string format
|
|
67
63
|
const convertAmount = (input: string | number): string => {
|
|
68
64
|
if (typeof input === 'number') {
|
|
65
|
+
if (input === 0 && !nullDisplay) {
|
|
66
|
+
return ""
|
|
67
|
+
}
|
|
69
68
|
return input.toFixed(2)
|
|
70
69
|
}
|
|
71
70
|
return input
|
|
@@ -82,9 +81,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
82
81
|
variantClass = '_bold'
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
const [
|
|
86
|
-
const decimal = (decimalPart || '00').padEnd(2, '0').slice(0, 2)
|
|
87
|
-
const whole = currencyAmount === '' ? '' : (wholePart === '' ? '0' : wholePart)
|
|
84
|
+
const [whole, decimal = '00'] = currencyAmount.split('.')
|
|
88
85
|
const ariaProps = buildAriaProps(aria)
|
|
89
86
|
const dataProps = buildDataProps(data)
|
|
90
87
|
const htmlProps = buildHtmlProps(htmlOptions)
|
|
@@ -138,7 +135,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
138
135
|
<Caption dark={dark}>{label}</Caption>
|
|
139
136
|
<div className={`pb_currency_wrapper${variantClass || emphasizedClass}`}>
|
|
140
137
|
{unstyled ? (
|
|
141
|
-
nullDisplay &&
|
|
138
|
+
nullDisplay && !amount ? (
|
|
142
139
|
<div>{nullDisplay}</div>
|
|
143
140
|
) : (
|
|
144
141
|
<>
|
|
@@ -151,7 +148,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
151
148
|
</>
|
|
152
149
|
)
|
|
153
150
|
) : (
|
|
154
|
-
nullDisplay &&
|
|
151
|
+
nullDisplay && !amount ? (
|
|
155
152
|
<Title
|
|
156
153
|
className="pb_currency_value"
|
|
157
154
|
dark={dark}
|
|
@@ -68,7 +68,7 @@ module Playbook
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def title_text
|
|
71
|
-
if null_display
|
|
71
|
+
if null_display
|
|
72
72
|
null_display
|
|
73
73
|
elsif swap_negative
|
|
74
74
|
absolute_amount(abbr_or_format_amount)
|
|
@@ -125,7 +125,14 @@ module Playbook
|
|
|
125
125
|
# Convert numeric input to string format
|
|
126
126
|
def convert_amount(input)
|
|
127
127
|
if input.is_a?(Numeric)
|
|
128
|
-
|
|
128
|
+
if input.zero? && null_display.nil?
|
|
129
|
+
""
|
|
130
|
+
else
|
|
131
|
+
format("%.2f", input)
|
|
132
|
+
end
|
|
133
|
+
# Handle string representations of zero
|
|
134
|
+
elsif input.to_s.strip.match?(/^-?0+(\.0+)?$/) && null_display.nil?
|
|
135
|
+
""
|
|
129
136
|
else
|
|
130
137
|
input.to_s
|
|
131
138
|
end
|
|
@@ -135,7 +142,6 @@ module Playbook
|
|
|
135
142
|
return "" if currency_amount.blank?
|
|
136
143
|
|
|
137
144
|
value = currency_amount.split(".").first
|
|
138
|
-
value = "0" if value.blank?
|
|
139
145
|
if comma_separator
|
|
140
146
|
number_with_delimiter(value.gsub(",", ""))
|
|
141
147
|
else
|
|
@@ -146,8 +152,7 @@ module Playbook
|
|
|
146
152
|
def decimal_value
|
|
147
153
|
return "00" if currency_amount.blank?
|
|
148
154
|
|
|
149
|
-
|
|
150
|
-
fraction.ljust(2, "0")[0, 2]
|
|
155
|
+
currency_amount.split(".")[1] || "00"
|
|
151
156
|
end
|
|
152
157
|
|
|
153
158
|
def units_element
|
|
@@ -178,48 +178,5 @@ test('handles numeric amounts correctly', () => {
|
|
|
178
178
|
expect(screen.getByTestId('test-numeric-no-symbol')).toHaveTextContent('400.50')
|
|
179
179
|
expect(screen.getByTestId('test-numeric-medium-size')).toHaveTextContent('$500.55')
|
|
180
180
|
expect(screen.getByTestId('test-numeric-negative')).toHaveTextContent('-$600.70')
|
|
181
|
-
expect(screen.getByTestId('test-numeric-null')).toHaveTextContent('
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
test('renders zero values with leading digit', () => {
|
|
185
|
-
render(
|
|
186
|
-
<>
|
|
187
|
-
<Currency
|
|
188
|
-
amount="0"
|
|
189
|
-
data={{ testid: 'test-string-zero' }}
|
|
190
|
-
/>
|
|
191
|
-
<Currency
|
|
192
|
-
amount={0}
|
|
193
|
-
data={{ testid: 'test-numeric-zero' }}
|
|
194
|
-
/>
|
|
195
|
-
</>
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
expect(screen.getByTestId('test-string-zero')).toHaveTextContent('$0.00')
|
|
199
|
-
expect(screen.getByTestId('test-numeric-zero')).toHaveTextContent('$0.00')
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
test('normalizes string zero with single decimal digit to .00', () => {
|
|
203
|
-
render(
|
|
204
|
-
<Currency
|
|
205
|
-
amount="0.0"
|
|
206
|
-
commaSeparator
|
|
207
|
-
data={{ testid: 'test-string-zero-single-decimal' }}
|
|
208
|
-
/>
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
expect(screen.getByTestId('test-string-zero-single-decimal')).toHaveTextContent('$0.00')
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
test('nullDisplay only applies when amount is empty', () => {
|
|
215
|
-
render(
|
|
216
|
-
<Currency
|
|
217
|
-
amount="-.53"
|
|
218
|
-
data={{ testid: 'test-null-display-negative' }}
|
|
219
|
-
nullDisplay="$0.00"
|
|
220
|
-
/>
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
expect(screen.getByTestId('test-null-display-negative')).toHaveTextContent('-$')
|
|
224
|
-
expect(screen.getByTestId('test-null-display-negative')).not.toHaveTextContent('$0.00')
|
|
181
|
+
expect(screen.getByTestId('test-numeric-null')).toHaveTextContent('$.00')
|
|
225
182
|
})
|
|
@@ -8,25 +8,6 @@
|
|
|
8
8
|
cursor: grab;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
&.is_touch_active {
|
|
12
|
-
.pb_draggable_handle,
|
|
13
|
-
.card_draggable_handle {
|
|
14
|
-
color: $text_lt_default;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.pb_draggable_handle,
|
|
19
|
-
.card_draggable_handle {
|
|
20
|
-
touch-action: none;
|
|
21
|
-
-webkit-touch-callout: none;
|
|
22
|
-
user-select: none;
|
|
23
|
-
cursor: grab;
|
|
24
|
-
|
|
25
|
-
&:active {
|
|
26
|
-
color: $text_lt_default;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
11
|
&.is_dragging {
|
|
31
12
|
position: relative;
|
|
32
13
|
|
|
@@ -5,5 +5,3 @@ Use the `draggable` kit and manage state as shown.
|
|
|
5
5
|
`draggable/draggable_container` kit creates the container within which the cards can be dragged and dropped.
|
|
6
6
|
|
|
7
7
|
The Card kit is optimized to work with the draggable kit. To enable drag, use the `draggable_item` and `drag_id` props on the Card kit as shown. An additional optional boolean prop (set to true by default) of `drag_handle` is also available to show the drag handle icon.
|
|
8
|
-
|
|
9
|
-
On touch devices, drag from the grip handle (no long press). Swiping the card body scrolls as usual. Keep `drag_handle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
@@ -6,5 +6,4 @@ Use `DraggableProvider` and manage state as shown.
|
|
|
6
6
|
|
|
7
7
|
The Card kit is optimized to work with the draggable kit. To enable drag, use the `draggableItem` and `dragId` props on the Card kit as shown. An additional optional boolean prop (set to true by default) of `dragHandle` is also available to show the drag handle icon.
|
|
8
8
|
|
|
9
|
-
On touch devices, drag from the grip handle (no long press). Swiping the card body scrolls as usual. Keep `dragHandle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
10
9
|
|
|
@@ -3,5 +3,3 @@ For a simplified version of the Draggable API for the List kit, you can do the f
|
|
|
3
3
|
The List kit is optimized to work with the draggable kit. To enable drag, use the `enable_drag` prop on List kit with an array of the included items AND `drag_id` prop on ListItems. You will also need to include the `items` prop containing your array of listed items for the Draggable API.
|
|
4
4
|
|
|
5
5
|
An additional optional boolean prop (set to true by default) of `drag_handle` is also available on ListItem kit to show the drag handle icon.
|
|
6
|
-
|
|
7
|
-
On touch devices, drag from the grip handle (no long press). Swiping the rest of the row scrolls as usual. Keep `drag_handle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
@@ -2,6 +2,4 @@ For a simplified version of the Draggable API for the List kit, you can do the f
|
|
|
2
2
|
|
|
3
3
|
Use `DraggableProvider` and manage state as shown.
|
|
4
4
|
|
|
5
|
-
The List kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on List kit AND `dragId` prop on ListItem. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on
|
|
6
|
-
|
|
7
|
-
On touch devices, drag from the grip handle (no long press). Swiping the rest of the row scrolls as usual. Keep `dragHandle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
5
|
+
The List kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on List kit AND `dragId` prop on ListItem. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on List kit to show the drag handle icon.
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
For a simplified version of the Draggable API for the SelectableList kit, you can do the following:
|
|
2
2
|
|
|
3
|
-
The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enable_drag` prop on SelectableList kit AND `drag_id` prop within the SelectableList kit prop. An additional optional boolean prop (set to true by default) of `drag_handle` is also available on SelectableList kit to show the drag handle icon.
|
|
4
|
-
|
|
5
|
-
On touch devices, drag from the grip handle (no long press). Swiping the rest of the row scrolls as usual. Keep `drag_handle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
3
|
+
The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enable_drag` prop on SelectableList kit AND `drag_id` prop within the SelectableList kit prop. An additional optional boolean prop (set to true by default) of `drag_handle` is also available on SelectableList kit to show the drag handle icon.
|
|
@@ -2,6 +2,4 @@ For a simplified version of the Draggable API for the SelectableList kit, you ca
|
|
|
2
2
|
|
|
3
3
|
Use `DraggableProvider` and manage state as shown.
|
|
4
4
|
|
|
5
|
-
The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on SelectableList kit AND `dragId` prop on SelectableList.Item. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on SelectableList kit to show the drag handle icon.
|
|
6
|
-
|
|
7
|
-
On touch devices, drag from the grip handle (no long press). Swiping the rest of the row scrolls as usual. Keep `dragHandle` enabled on mobile. Desktop mouse drag is unchanged.
|
|
5
|
+
The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on SelectableList kit AND `dragId` prop on SelectableList.Item. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on SelectableList kit to show the drag handle icon.
|
|
@@ -211,14 +211,6 @@ test("Attached draggable HTML attributes", () => {
|
|
|
211
211
|
expect(item).toHaveAttribute("draggable");
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
test("draggable items expose data-pb-drag-id for touch reordering", () => {
|
|
215
|
-
render(<DefaultDraggableKit />);
|
|
216
|
-
const kit = screen.getByTestId(testId);
|
|
217
|
-
|
|
218
|
-
const item = kit.querySelector(".pb_draggable_item");
|
|
219
|
-
expect(item).toHaveAttribute("data-pb-drag-id", "1");
|
|
220
|
-
});
|
|
221
|
-
|
|
222
214
|
test("generated dragHandle with List", () => {
|
|
223
215
|
render(<DraggableKitWithList />);
|
|
224
216
|
const kit = screen.getByTestId(testId);
|
|
@@ -310,14 +302,6 @@ const DraggableMultipleContainers = () => {
|
|
|
310
302
|
);
|
|
311
303
|
};
|
|
312
304
|
|
|
313
|
-
test("draggable containers expose data-pb-drag-container when provided", () => {
|
|
314
|
-
render(<DraggableMultipleContainers />);
|
|
315
|
-
const kit = screen.getByTestId(testId);
|
|
316
|
-
|
|
317
|
-
const container = kit.querySelector('[data-testid="container-To Do"]');
|
|
318
|
-
expect(container).toHaveAttribute("data-pb-drag-container", "To Do");
|
|
319
|
-
});
|
|
320
|
-
|
|
321
305
|
test("renders multiple containers with correct items", () => {
|
|
322
306
|
render(<DraggableMultipleContainers />);
|
|
323
307
|
|
|
@@ -2,32 +2,7 @@ import PbEnhancedElement from "../pb_enhanced_element";
|
|
|
2
2
|
|
|
3
3
|
const DRAGGABLE_SELECTOR = "[data-pb-draggable]";
|
|
4
4
|
const DRAGGABLE_CONTAINER = ".pb_draggable_container";
|
|
5
|
-
const DRAG_HANDLE_SELECTOR = ".pb_draggable_handle, .card_draggable_handle";
|
|
6
5
|
const NEEDS_CLONE = ["shadow", "outline", "line"]; // clone only for these types
|
|
7
|
-
const DRAG_THRESHOLD_PX = 5;
|
|
8
|
-
|
|
9
|
-
const isTouchDragDevice = () => {
|
|
10
|
-
const hasTouch = "ontouchstart" in window;
|
|
11
|
-
const hasCoarsePointer =
|
|
12
|
-
typeof window.matchMedia === "function" &&
|
|
13
|
-
window.matchMedia("(hover: none) and (pointer: coarse)").matches;
|
|
14
|
-
|
|
15
|
-
return hasTouch || hasCoarsePointer;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const getDragIdFromElement = (element) => {
|
|
19
|
-
const item = element?.closest(".pb_draggable_item");
|
|
20
|
-
if (!item) return null;
|
|
21
|
-
|
|
22
|
-
return item.getAttribute("data-pb-drag-id") || item.id;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const getContainerFromElement = (element) => {
|
|
26
|
-
const container = element?.closest(DRAGGABLE_CONTAINER);
|
|
27
|
-
if (!container) return null;
|
|
28
|
-
|
|
29
|
-
return container.getAttribute("data-pb-drag-container") || container.id;
|
|
30
|
-
};
|
|
31
6
|
|
|
32
7
|
export default class PbDraggable extends PbEnhancedElement {
|
|
33
8
|
static get selector() { return DRAGGABLE_SELECTOR; }
|
|
@@ -46,8 +21,6 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
|
46
21
|
this.hasMultipleContainers = false;
|
|
47
22
|
this.dragZoneType = "";
|
|
48
23
|
this.dragZoneColor = "";
|
|
49
|
-
this.useTouchDrag = isTouchDragDevice();
|
|
50
|
-
this.touchCleanups = [];
|
|
51
24
|
|
|
52
25
|
// If DOM is already loaded, bind immediately; otherwise wait for DOMContentLoaded
|
|
53
26
|
if (document.readyState === "loading") {
|
|
@@ -81,14 +54,9 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
|
81
54
|
|
|
82
55
|
this.element.querySelectorAll(".pb_draggable_item")
|
|
83
56
|
.forEach(item => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} else {
|
|
88
|
-
item.addEventListener("dragstart", this.handleDragStart.bind(this));
|
|
89
|
-
item.addEventListener("dragend", this.handleDragEnd.bind(this));
|
|
90
|
-
item.addEventListener("dragenter", this.handleDragEnter.bind(this));
|
|
91
|
-
}
|
|
57
|
+
item.addEventListener("dragstart", this.handleDragStart.bind(this));
|
|
58
|
+
item.addEventListener("dragend", this.handleDragEnd.bind(this));
|
|
59
|
+
item.addEventListener("dragenter", this.handleDragEnter.bind(this));
|
|
92
60
|
});
|
|
93
61
|
|
|
94
62
|
containers.forEach(c => {
|
|
@@ -97,118 +65,8 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
|
97
65
|
});
|
|
98
66
|
}
|
|
99
67
|
|
|
100
|
-
bindTouchDragForItem(item) {
|
|
101
|
-
const handle = item.querySelector(DRAG_HANDLE_SELECTOR);
|
|
102
|
-
const dragTarget = handle || item;
|
|
103
|
-
const state = {
|
|
104
|
-
active: false,
|
|
105
|
-
dragging: false,
|
|
106
|
-
startX: 0,
|
|
107
|
-
startY: 0,
|
|
108
|
-
lastTargetDragId: null,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const resetState = () => {
|
|
112
|
-
state.active = false;
|
|
113
|
-
state.dragging = false;
|
|
114
|
-
state.lastTargetDragId = null;
|
|
115
|
-
item.classList.remove("is_touch_active");
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const pointerEventFromTouch = (touch, target) => ({
|
|
119
|
-
target,
|
|
120
|
-
clientX: touch.clientX,
|
|
121
|
-
clientY: touch.clientY,
|
|
122
|
-
preventDefault: () => undefined,
|
|
123
|
-
stopPropagation: () => undefined,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const onTouchStart = (event) => {
|
|
127
|
-
if (handle && !handle.contains(event.target)) return;
|
|
128
|
-
|
|
129
|
-
const touch = event.touches[0];
|
|
130
|
-
if (!touch) return;
|
|
131
|
-
|
|
132
|
-
state.active = true;
|
|
133
|
-
state.startX = touch.clientX;
|
|
134
|
-
state.startY = touch.clientY;
|
|
135
|
-
item.classList.add("is_touch_active");
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const onTouchMove = (event) => {
|
|
139
|
-
if (!state.active) return;
|
|
140
|
-
|
|
141
|
-
const touch = event.touches[0];
|
|
142
|
-
if (!touch) return;
|
|
143
|
-
|
|
144
|
-
if (!state.dragging) {
|
|
145
|
-
const deltaX = touch.clientX - state.startX;
|
|
146
|
-
const deltaY = touch.clientY - state.startY;
|
|
147
|
-
|
|
148
|
-
if (Math.hypot(deltaX, deltaY) < DRAG_THRESHOLD_PX) return;
|
|
149
|
-
|
|
150
|
-
state.dragging = true;
|
|
151
|
-
this.handleDragStart(pointerEventFromTouch(touch, item));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
event.preventDefault();
|
|
155
|
-
|
|
156
|
-
const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
157
|
-
const targetItem = elementBelow?.closest(".pb_draggable_item");
|
|
158
|
-
const targetDragId = getDragIdFromElement(elementBelow);
|
|
159
|
-
|
|
160
|
-
if (targetItem && targetItem !== item && targetDragId !== state.lastTargetDragId) {
|
|
161
|
-
state.lastTargetDragId = targetDragId;
|
|
162
|
-
this.handleDragEnter(pointerEventFromTouch(touch, targetItem));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const targetContainer = getContainerFromElement(elementBelow);
|
|
166
|
-
if (targetContainer) {
|
|
167
|
-
const containerElement = elementBelow.closest(DRAGGABLE_CONTAINER);
|
|
168
|
-
if (containerElement) {
|
|
169
|
-
this.handleDragOver(pointerEventFromTouch(touch, containerElement));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const finishTouchDrag = (touch) => {
|
|
175
|
-
if (!state.active) return;
|
|
176
|
-
|
|
177
|
-
if (state.dragging && touch) {
|
|
178
|
-
const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
179
|
-
const containerElement = elementBelow?.closest(DRAGGABLE_CONTAINER);
|
|
180
|
-
|
|
181
|
-
if (containerElement) {
|
|
182
|
-
this.handleDrop(pointerEventFromTouch(touch, containerElement));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
this.handleDragEnd({ target: item });
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
resetState();
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const onTouchEnd = (event) => finishTouchDrag(event.changedTouches[0]);
|
|
192
|
-
const onTouchCancel = (event) => finishTouchDrag(event.changedTouches[0]);
|
|
193
|
-
|
|
194
|
-
dragTarget.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
195
|
-
dragTarget.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
196
|
-
dragTarget.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
197
|
-
dragTarget.addEventListener("touchcancel", onTouchCancel, { passive: true });
|
|
198
|
-
|
|
199
|
-
return () => {
|
|
200
|
-
dragTarget.removeEventListener("touchstart", onTouchStart);
|
|
201
|
-
dragTarget.removeEventListener("touchmove", onTouchMove);
|
|
202
|
-
dragTarget.removeEventListener("touchend", onTouchEnd);
|
|
203
|
-
dragTarget.removeEventListener("touchcancel", onTouchCancel);
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
68
|
/* ---------------- DRAG START ---------------- */
|
|
208
69
|
handleDragStart(event) {
|
|
209
|
-
const item = event.target.closest(".pb_draggable_item");
|
|
210
|
-
if (!item) return;
|
|
211
|
-
|
|
212
70
|
// Needed to prevent images within draggable items from being independently draggable
|
|
213
71
|
// Needed if using Image kit in draggable items
|
|
214
72
|
if (event.target.tagName.toLowerCase() === "img") {
|
|
@@ -216,9 +74,9 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
|
216
74
|
return;
|
|
217
75
|
}
|
|
218
76
|
|
|
219
|
-
const container =
|
|
220
|
-
this.draggedItem =
|
|
221
|
-
this.draggedItemId =
|
|
77
|
+
const container = event.target.closest(DRAGGABLE_CONTAINER);
|
|
78
|
+
this.draggedItem = event.target;
|
|
79
|
+
this.draggedItemId = event.target.id;
|
|
222
80
|
this.dragZoneType = this.element.dataset.dropZoneType || "";
|
|
223
81
|
this.dragZoneColor = this.element.dataset.dropZoneColor || "";
|
|
224
82
|
|
|
@@ -264,7 +122,7 @@ export default class PbDraggable extends PbEnhancedElement {
|
|
|
264
122
|
}
|
|
265
123
|
|
|
266
124
|
if (this.dragZoneType !== "line") {
|
|
267
|
-
requestAnimationFrame(() => (
|
|
125
|
+
requestAnimationFrame(() => (event.target.style.opacity = "0.5"));
|
|
268
126
|
}
|
|
269
127
|
}
|
|
270
128
|
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
import { globalProps } from "../../utilities/globalProps";
|
|
10
10
|
import { DraggableContext } from "../context";
|
|
11
11
|
import { noop } from '../../utilities/object'
|
|
12
|
-
import { bindTouchDrag, isTouchDragDevice } from "../utilities/touchDrag";
|
|
13
12
|
|
|
14
13
|
type DraggableItemProps = {
|
|
15
14
|
aria?: { [key: string]: string };
|
|
@@ -55,76 +54,12 @@ const DraggableItem = (props: DraggableItemProps) => {
|
|
|
55
54
|
handleDragStart,
|
|
56
55
|
handleDragEnter,
|
|
57
56
|
handleDragEnd,
|
|
58
|
-
handleDrop,
|
|
59
|
-
handleDragOver,
|
|
60
57
|
dropZone = 'ghost',
|
|
61
58
|
dropZoneColor = 'neutral',
|
|
62
59
|
direction = 'horizontal'
|
|
63
60
|
} = DraggableContext();
|
|
64
61
|
|
|
65
62
|
const itemRef = React.useRef<HTMLElement>(null);
|
|
66
|
-
const [useTouchDrag, setUseTouchDrag] = React.useState(false);
|
|
67
|
-
const handlersRef = React.useRef({
|
|
68
|
-
handleDragStart,
|
|
69
|
-
handleDragEnter,
|
|
70
|
-
handleDragEnd,
|
|
71
|
-
handleDrop,
|
|
72
|
-
handleDragOver,
|
|
73
|
-
onDragStart,
|
|
74
|
-
onDragEnter,
|
|
75
|
-
onDragOver,
|
|
76
|
-
onDrop,
|
|
77
|
-
onDragEnd,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
handlersRef.current = {
|
|
81
|
-
handleDragStart,
|
|
82
|
-
handleDragEnter,
|
|
83
|
-
handleDragEnd,
|
|
84
|
-
handleDrop,
|
|
85
|
-
handleDragOver,
|
|
86
|
-
onDragStart,
|
|
87
|
-
onDragEnter,
|
|
88
|
-
onDragOver,
|
|
89
|
-
onDrop,
|
|
90
|
-
onDragEnd,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
React.useEffect(() => {
|
|
94
|
-
setUseTouchDrag(isTouchDragDevice());
|
|
95
|
-
}, []);
|
|
96
|
-
|
|
97
|
-
React.useEffect(() => {
|
|
98
|
-
if (!useTouchDrag || !itemRef.current || !dragId) return;
|
|
99
|
-
|
|
100
|
-
return bindTouchDrag({
|
|
101
|
-
dragId,
|
|
102
|
-
container,
|
|
103
|
-
itemElement: itemRef.current,
|
|
104
|
-
handlers: {
|
|
105
|
-
onDragStart: (id, itemContainer) => {
|
|
106
|
-
handlersRef.current.handleDragStart(id, itemContainer);
|
|
107
|
-
handlersRef.current.onDragStart();
|
|
108
|
-
},
|
|
109
|
-
onDragEnter: (targetDragId, targetContainer) => {
|
|
110
|
-
handlersRef.current.handleDragEnter(targetDragId, targetContainer);
|
|
111
|
-
handlersRef.current.onDragEnter();
|
|
112
|
-
},
|
|
113
|
-
onDragOver: (event, targetContainer) => {
|
|
114
|
-
handlersRef.current.handleDragOver(event, targetContainer);
|
|
115
|
-
handlersRef.current.onDragOver();
|
|
116
|
-
},
|
|
117
|
-
onDrop: (dropContainer) => {
|
|
118
|
-
handlersRef.current.handleDrop(dropContainer);
|
|
119
|
-
handlersRef.current.onDrop();
|
|
120
|
-
},
|
|
121
|
-
onDragEnd: () => {
|
|
122
|
-
handlersRef.current.handleDragEnd();
|
|
123
|
-
handlersRef.current.onDragEnd();
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
}, [useTouchDrag, dragId, container]);
|
|
128
63
|
|
|
129
64
|
const ariaProps = buildAriaProps(aria);
|
|
130
65
|
const dataProps = buildDataProps(data);
|
|
@@ -187,8 +122,7 @@ const DraggableItem = (props: DraggableItemProps) => {
|
|
|
187
122
|
{...dataProps}
|
|
188
123
|
{...htmlProps}
|
|
189
124
|
className={classes}
|
|
190
|
-
|
|
191
|
-
draggable={!useTouchDrag}
|
|
125
|
+
draggable
|
|
192
126
|
id={id}
|
|
193
127
|
key={dragId}
|
|
194
128
|
onDrag={onDrag}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= pb_rails("icon", props: { icon: "powergon", font_style: "fak", fixed_width: true, size: "5x" }) %>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import Icon from '../_icon'
|
|
4
|
+
|
|
5
|
+
import '../../../../../../playbook-website/app/javascript/scripts/custom-icons'
|
|
6
|
+
|
|
7
|
+
const IconFaKit = (props) => {
|
|
8
|
+
return (
|
|
9
|
+
<div>
|
|
10
|
+
<Icon
|
|
11
|
+
{...props}
|
|
12
|
+
fixedWidth
|
|
13
|
+
fontStyle="fak"
|
|
14
|
+
icon="powergon"
|
|
15
|
+
size="5x"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default IconFaKit
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Our Icon kit allows integration with [FontAwesome's custom kit](https://fontawesome.com/v6/docs/web/setup/use-kit#contentHeader) functionality out-of-the-box.
|
|
2
|
+
|
|
3
|
+
All you need to do is 3 things:
|
|
4
|
+
1) Import your custom-icon.js file as outlined in the FontAwesome docs.
|
|
5
|
+
2) Use our fontStyle prop called "fak" so that our Icon component knows you are using a "fa-kit" icon.
|
|
6
|
+
3) Pass in your FaKit name as a string to our icon prop (This is the name that you designated when you uploaded the icon on their site).
|
|
7
|
+
|
|
@@ -8,6 +8,7 @@ examples:
|
|
|
8
8
|
- icon_border: Icon Border
|
|
9
9
|
- icon_sizes: Icon Sizes
|
|
10
10
|
- icon_custom: Icon Custom
|
|
11
|
+
- icon_fa_kit: Icon with FontAwesome Kit
|
|
11
12
|
- icon_color: Icon Color
|
|
12
13
|
|
|
13
14
|
react:
|
|
@@ -19,6 +20,7 @@ examples:
|
|
|
19
20
|
- icon_border: Icon Border
|
|
20
21
|
- icon_sizes: Icon Sizes
|
|
21
22
|
- icon_custom: Icon Custom
|
|
23
|
+
- icon_fa_kit: Icon with FontAwesome Kit
|
|
22
24
|
- icon_color: Icon Color
|
|
23
25
|
|
|
24
26
|
swift:
|
|
@@ -6,4 +6,5 @@ export { default as IconPull } from './_icon_pull.jsx'
|
|
|
6
6
|
export { default as IconBorder } from './_icon_border.jsx'
|
|
7
7
|
export { default as IconSizes } from './_icon_sizes.jsx'
|
|
8
8
|
export { default as IconCustom } from './_icon_custom.jsx'
|
|
9
|
+
export { default as IconFaKit} from './_icon_fa_kit.jsx'
|
|
9
10
|
export { default as IconColor } from './_icon_color.jsx'
|