playbook_ui 16.10.0.pre.alpha.play300617429 → 16.10.0.pre.alpha.play300617505

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc61e3b1cf418d10b8c89717465ec82d728f918711ab223e03065119d0e6ebe2
4
- data.tar.gz: a59e2de7ba4dbba8477676d95664dd0442148d2effd74ad5c9f1162e7e451693
3
+ metadata.gz: b6044e67e19269e1a92b4676fa5016bed0216700a6dcacfb20cc7d51cf260d7c
4
+ data.tar.gz: b6b32bf00d34dda342226e78fcbe12c10998afd6834dabc39897de96a8800b33
5
5
  SHA512:
6
- metadata.gz: 0dd024e07261c2ead3b178c94561265f0a64caa2f07d177c71f2ef325163243c630d4903290151e7cf3eff0c70c3a1840ba56d646d31c6fff49107c37e1066e9
7
- data.tar.gz: d16f9553b4b72dca3f94d39b9d3dc29529bf17c0dcb24b0154fe127e610298f9f155d1533df6e2f90a7ef6c86d5078c67b4f8dc102fe6a7a6d97f2053a5d87ac
6
+ metadata.gz: 0ffcf33ef0bb707a2b5a7cc34755d26eddc2ea8a0b980f60f4dcd13befa32d55965228809c6996b103e83558100bed90f521a2cdd43e17e45b8d1ba5279387db
7
+ data.tar.gz: 3380b0f9a955d1d682109399d8dc369102594e63e865fe2b50433939eb1a53c993fb8e36099dbfc71fb08d3787aed44790371b2972f305aac09c6df0e34aa8a5
@@ -32,9 +32,9 @@ exports[`html structure is correct 1`] = `
32
32
  class="pb_custom_icon svg-inline--fa color_text_lt_lighter svg_lg svg_fw"
33
33
  color="currentColor"
34
34
  fill="none"
35
- height="auto"
35
+ height="1.5em"
36
36
  viewBox="0 0 30 25"
37
- width="auto"
37
+ width="1.5em"
38
38
  xmlns="http://www.w3.org/2000/svg"
39
39
  >
40
40
  <path
@@ -0,0 +1,66 @@
1
+ <div id="file-upload-remove-replace">
2
+ <%= pb_rails("list", props: { id: "selected-files-list", margin_bottom: "sm" }) %>
3
+
4
+ <%= pb_rails("file_upload", props: {
5
+ id: "remove_replace",
6
+ input_options: { multiple: true },
7
+ }) %>
8
+ </div>
9
+
10
+ <template id="file-list-item-template">
11
+ <%= pb_rails("list/item") do %>
12
+ <%= pb_rails("flex", props: { align: "center", justify: "between", width: "100%" }) do %>
13
+ <%= pb_rails("body", props: { data: { file_name: true } }) %>
14
+ <%= pb_rails("circle_icon_button", props: {
15
+ icon: "times",
16
+ variant: "secondary",
17
+ input_options: { classname: "remove-file-button" },
18
+ }) %>
19
+ <% end %>
20
+ <% end %>
21
+ </template>
22
+
23
+ <%= javascript_tag defer: "defer" do %>
24
+ document.addEventListener("DOMContentLoaded", function () {
25
+ const fileInput = document.getElementById("upload-remove_replace")
26
+ const list = document.getElementById("selected-files-list")
27
+ const template = document.getElementById("file-list-item-template")
28
+ let files = []
29
+
30
+ if (!fileInput || !list || !template) return
31
+
32
+ function syncInput() {
33
+ const dataTransfer = new DataTransfer()
34
+ files.forEach((file) => dataTransfer.items.add(file))
35
+ fileInput.files = dataTransfer.files
36
+ }
37
+
38
+ function render() {
39
+ list.innerHTML = ""
40
+
41
+ files.forEach((file, index) => {
42
+ const clone = template.content.cloneNode(true)
43
+ const nameElement = clone.querySelector("[data-file-name]")
44
+ const removeButton = clone.querySelector(".remove-file-button")
45
+
46
+ nameElement.textContent = file.name
47
+ removeButton.addEventListener("click", function (event) {
48
+ event.preventDefault()
49
+ event.stopPropagation()
50
+ files = files.filter((_, fileIndex) => fileIndex !== index)
51
+ syncInput()
52
+ render()
53
+ })
54
+
55
+ list.appendChild(clone)
56
+ })
57
+ }
58
+
59
+ fileInput.addEventListener("change", function () {
60
+ const newFiles = Array.from(fileInput.files)
61
+ files = [...files, ...newFiles]
62
+ syncInput()
63
+ render()
64
+ })
65
+ })
66
+ <% end %>
@@ -0,0 +1,53 @@
1
+
2
+ import React, { useState } from 'react'
3
+
4
+ import Body from '../../pb_body/_body'
5
+ import CircleIconButton from '../../pb_circle_icon_button/_circle_icon_button'
6
+ import FileUpload from '../../pb_file_upload/_file_upload'
7
+ import Flex from '../../pb_flex/_flex'
8
+ import List from '../../pb_list/_list'
9
+ import ListItem from '../../pb_list/_list_item'
10
+
11
+ const FileUploadRemoveReplace = (props) => {
12
+ const [filesToUpload, setFilesToUpload] = useState([])
13
+
14
+ const handleOnFilesAccepted = (files) => {
15
+ setFilesToUpload([...filesToUpload, ...files])
16
+ }
17
+
18
+ const handleRemoveFile = (index) => {
19
+ setFilesToUpload(filesToUpload.filter((_, fileIndex) => fileIndex !== index))
20
+ }
21
+
22
+ return (
23
+ <div>
24
+ {filesToUpload.length > 0 && (
25
+ <List marginBottom="sm">
26
+ {filesToUpload.map((file, index) => (
27
+ <ListItem key={`${file.name}-${index}`}>
28
+ <Flex
29
+ align="center"
30
+ justify="between"
31
+ width="100%"
32
+ >
33
+ <Body text={file.name} />
34
+ <CircleIconButton
35
+ aria={{ label: `Remove ${file.name}` }}
36
+ icon="times"
37
+ onClick={() => handleRemoveFile(index)}
38
+ variant="secondary"
39
+ />
40
+ </Flex>
41
+ </ListItem>
42
+ ))}
43
+ </List>
44
+ )}
45
+ <FileUpload
46
+ onFilesAccepted={handleOnFilesAccepted}
47
+ {...props}
48
+ />
49
+ </div>
50
+ )
51
+ }
52
+
53
+ export default FileUploadRemoveReplace
@@ -0,0 +1,5 @@
1
+ The File Upload kit does not include built-in remove or replace behavior. Manage selected files in application state and compose the kit with other Playbook components.
2
+
3
+ **Remove** — Track accepted files in state and filter out the file to remove. In React, pair `List` with `CircleIconButton`. In Rails, listen for `change` on the file input, keep files in a JavaScript array, and use `DataTransfer` to sync the input when a file is removed.
4
+
5
+ **Replace** — Selecting a new file on the native Rails input replaces the current selection. For single-file React workflows, set state to the newly accepted files instead of appending: `setFilesToUpload(files)`.
@@ -4,6 +4,7 @@ examples:
4
4
  - file_upload_default: File Upload
5
5
  - file_upload_custom: Custom
6
6
  - file_upload_error: Error
7
+ - file_upload_remove_replace: Remove and Replace
7
8
 
8
9
  react:
9
10
  - file_upload_default: Default List of files to upload
@@ -11,4 +12,5 @@ examples:
11
12
  - file_upload_custom_message: Add a custom message
12
13
  - file_upload_custom_description: Add your one accepted files description
13
14
  - file_upload_max_size: Set a file size limit
14
- - file_upload_error: Error
15
+ - file_upload_error: Error
16
+ - file_upload_remove_replace: Remove and Replace
@@ -4,3 +4,4 @@ export { default as FileUploadCustomMessage } from './_file_upload_custom_messag
4
4
  export { default as FileUploadCustomDescription } from './_file_upload_custom_description.jsx'
5
5
  export { default as FileUploadMaxSize } from './_file_upload_max_size.jsx'
6
6
  export { default as FileUploadError } from './_file_upload_error.jsx'
7
+ export { default as FileUploadRemoveReplace } from './_file_upload_remove_replace.jsx'
@@ -125,8 +125,6 @@ module Playbook
125
125
 
126
126
  svg["class"] = %w[pb_custom_icon svg-inline--fa].concat([object.custom_icon_classname]).join(" ")
127
127
  svg["id"] = object.id
128
- svg["height"] = "auto"
129
- svg["width"] = "auto"
130
128
  svg["tabindex"] = object.tabindex
131
129
  fill_color = object.color || "currentColor"
132
130
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Playbook
4
4
  PREVIOUS_VERSION = "16.10.0"
5
- VERSION = "16.10.0.pre.alpha.play300617429"
5
+ VERSION = "16.10.0.pre.alpha.play300617505"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.10.0.pre.alpha.play300617429
4
+ version: 16.10.0.pre.alpha.play300617505
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2026-07-02 00:00:00.000000000 Z
12
+ date: 2026-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -1630,6 +1630,9 @@ files:
1630
1630
  - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.html.erb
1631
1631
  - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.jsx
1632
1632
  - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_max_size.jsx
1633
+ - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.html.erb
1634
+ - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.jsx
1635
+ - app/pb_kits/playbook/pb_file_upload/docs/_file_upload_remove_replace.md
1633
1636
  - app/pb_kits/playbook/pb_file_upload/docs/_playground.json
1634
1637
  - app/pb_kits/playbook/pb_file_upload/docs/_playground.overrides.json
1635
1638
  - app/pb_kits/playbook/pb_file_upload/docs/example.yml