@@ -158,6 +158,80 @@ export default {
158158```
159159</docs >
160160
161+ <script setup lang="ts">
162+ import { computed , warn } from ' vue'
163+ import DOMPurify from ' dompurify'
164+
165+ const props = withDefaults (defineProps <{
166+ /**
167+ * Make the icon directional, meaning it is langauge direction aware.
168+ * If the icon is placed in a right-to-left context it will be mirrored vertically.
169+ */
170+ directional? : boolean
171+
172+ /**
173+ * Set if the icon should be used as inline content e.g. within text.
174+ * By default the icon is made a block element for use inside `icon`-slots.
175+ */
176+ inline? : boolean
177+
178+ /**
179+ * Raw SVG string to render
180+ */
181+ svg? : string
182+
183+ /**
184+ * Label of the icon, used in aria-label
185+ */
186+ name? : string
187+
188+ /**
189+ * Raw SVG path to render. Takes precedence over the SVG string in the `svg` prop.
190+ */
191+ path? : string
192+
193+ /**
194+ * Size of the icon to show. Only use if not using within an icon slot.
195+ * Defaults to 20px which is the Nextcloud icon size for all icon slots.
196+ */
197+ size? : number | ' auto'
198+ }>(), {
199+ name: undefined ,
200+ path: ' ' ,
201+ size: 20 ,
202+ svg: ' ' ,
203+ })
204+
205+ /**
206+ * Icon size used in CSS
207+ */
208+ const iconSize = computed (() => typeof props .size === ' number' ? ` ${props .size }px ` : props .size )
209+
210+ /**
211+ * The sanitized SVG or undefined if path shall be used
212+ */
213+ const cleanSvg = computed (() => {
214+ if (! props .svg || props .path ) {
215+ return
216+ }
217+
218+ const svg = DOMPurify .sanitize (props .svg )
219+
220+ const svgDocument = new DOMParser ().parseFromString (svg , ' image/svg+xml' )
221+
222+ if (svgDocument .querySelector (' parsererror' )) {
223+ warn (' SVG is not valid' )
224+ return ' '
225+ }
226+
227+ if (svgDocument .documentElement .id ) {
228+ svgDocument .documentElement .removeAttribute (' id' )
229+ }
230+
231+ return svgDocument .documentElement .outerHTML
232+ })
233+ </script >
234+
161235<template >
162236 <span :aria-hidden =" name ? undefined : 'true'"
163237 :aria-label =" name || undefined"
@@ -175,100 +249,6 @@ export default {
175249 </span >
176250</template >
177251
178- <script >
179- import { warn } from ' vue'
180- import DOMPurify from ' dompurify'
181-
182- export default {
183- name: ' NcIconSvgWrapper' ,
184-
185- props: {
186- /**
187- * Make the icon directional, meaning it is langauge direction aware.
188- * If the icon is placed in a right-to-left context it will be mirrored vertically.
189- */
190- directional: {
191- type: Boolean ,
192- default: false ,
193- },
194-
195- /**
196- * Set if the icon should be used as inline content e.g. within text.
197- * By default the icon is made a block element for use inside `icon`-slots.
198- */
199- inline: {
200- type: Boolean ,
201- default: false ,
202- },
203-
204- /**
205- * Raw SVG string to render
206- */
207- svg: {
208- type: String ,
209- default: ' ' ,
210- },
211-
212- /**
213- * Label of the icon, used in aria-label
214- */
215- name: {
216- type: String ,
217- default: ' ' ,
218- },
219-
220- /**
221- * Raw SVG path to render. Takes precedence over the SVG string in the `svg` prop.
222- */
223- path: {
224- type: String ,
225- default: ' ' ,
226- },
227-
228- /**
229- * Size of the icon to show. Only use if not using within an icon slot.
230- * Defaults to 20px which is the Nextcloud icon size for all icon slots.
231- * @default 20
232- */
233- size: {
234- type: [Number , String ],
235- default: 20 ,
236- validator : (value ) => typeof value === ' number' || value === ' auto' ,
237- },
238- },
239-
240- computed: {
241- /**
242- * Icon size used in CSS
243- */
244- iconSize () {
245- return typeof this .size === ' number' ? ` ${ this .size } px` : this .size
246- },
247-
248- cleanSvg () {
249- if (! this .svg || this .path ) {
250- return
251- }
252-
253- const svg = DOMPurify .sanitize (this .svg )
254-
255- const svgDocument = new DOMParser ().parseFromString (svg, ' image/svg+xml' )
256-
257- if (svgDocument .querySelector (' parsererror' )) {
258- warn (' SVG is not valid' )
259- return ' '
260- }
261-
262- if (svgDocument .documentElement .id ) {
263- svgDocument .documentElement .removeAttribute (' id' )
264- }
265-
266- return svgDocument .documentElement .outerHTML
267- },
268- },
269- }
270- </script >
271-
272252<style lang="scss" scoped>
273253.icon-vue {
274254 display : flex ;
0 commit comments