Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
db8da7f
adds components list
dChiamp Jun 20, 2025
bd57d86
Update COMPONENTS.md
Sveb Jun 20, 2025
4fa76ad
Update COMPONENTS.md
Sveb Jun 20, 2025
b4dc86d
Update COMPONENTS.md
Sveb Jun 23, 2025
285e079
Update COMPONENTS.md
Sveb Jun 23, 2025
213a640
adds notes
dChiamp Jun 23, 2025
3004c74
Update COMPONENTS.md
Sveb Jun 24, 2025
7a1e0aa
Merge branch 'main' of https://github.com/funkhaus/ucla-library-websi…
dChiamp Jun 24, 2025
e955637
claimed component
austinblanchard Jun 24, 2025
d5e45d1
Update COMPONENTS.md
Sveb Jun 25, 2025
d49eaf5
claim a component
lux-v Jun 25, 2025
4b6cccf
claim a component
lux-v Jun 25, 2025
bfa79d4
Update COMPONENTS.md
Sveb Jun 25, 2025
4852133
Update COMPONENTS.md
Sveb Jun 25, 2025
2120974
Update COMPONENTS.md
Sveb Jun 25, 2025
c5d0581
take a component
lux-v Jun 25, 2025
af0a6b3
take a component
lux-v Jun 25, 2025
2e73be7
take a component
lux-v Jun 25, 2025
88bfe5e
Update COMPONENTS.md
austinblanchard Jun 25, 2025
22b88d7
Update COMPONENTS.md
Sveb Jun 26, 2025
498ab73
Adjust the component name - already exists
Sveb Jun 30, 2025
95a1121
UCLA - NotesAccordion
Sveb Jun 30, 2025
09c2fd0
take a component
lux-v Jul 1, 2025
0c75f77
take a component
lux-v Jul 1, 2025
a7bf5fa
Update COMPONENTS.md
Sveb Jul 1, 2025
069c123
Update COMPONENTS.md
Sveb Jul 7, 2025
cdb4a86
Update COMPONENTS.md
Sveb Jul 7, 2025
3bb30e3
ExcerptPod
Sveb Jul 7, 2025
8a29837
Update COMPONENTS.md
austinblanchard Jul 7, 2025
7bdfa7a
Update COMPONENTS.md - marking BentoPod
Sveb Jul 8, 2025
bc0154d
add component
lux-v Jul 8, 2025
597ef57
add component
lux-v Jul 8, 2025
02aafc7
Update COMPONENTS.md
austinblanchard Jul 8, 2025
e675c1b
Update COMPONENTS.md
austinblanchard Jul 8, 2025
2933c6d
take a component
lux-v Jul 9, 2025
d5c665a
take a component
lux-v Jul 9, 2025
e539e14
fix component description
lux-v Jul 9, 2025
4808e2d
Update COMPONENTS.md
Sveb Jul 10, 2025
e372e04
Update COMPONENTS.md
Sveb Jul 10, 2025
7d5d656
change component's name
lux-v Jul 11, 2025
ed656cf
Update COMPONENTS.md
Sveb Jul 14, 2025
877fb65
take a component
lux-v Jul 14, 2025
741d21e
Update NotesAccordion.vue
Sveb Jul 15, 2025
348494b
take a component
lux-v Jul 15, 2025
edc6600
clean up
Sveb Jul 15, 2025
0ffe143
Clean up props
Sveb Jul 15, 2025
45e6cf7
take a component
lux-v Jul 16, 2025
183375c
remove AssetFeaturedImage definition
lux-v Jul 16, 2025
ee9dd92
take a component
lux-v Jul 16, 2025
62919e6
take a components
lux-v Jul 16, 2025
51430d6
take a components
lux-v Jul 16, 2025
f6de890
take a component
lux-v Jul 16, 2025
76226de
take a component
lux-v Jul 16, 2025
d78dda6
add a new line
lux-v Jul 16, 2025
7388620
add detailed component description
lux-v Jul 16, 2025
63b619b
add detailed component description
lux-v Jul 16, 2025
e277dbe
take a component
lux-v Jul 16, 2025
08e03ec
update component description
lux-v Jul 16, 2025
0ee907a
Adds a button component
Sveb Jul 17, 2025
864171d
Update COMPONENTS.md
Sveb Jul 17, 2025
1bb618a
Update COMPONENTS.md
Sveb Jul 17, 2025
54df91d
Update COMPONENTS.md
Sveb Jul 17, 2025
0ed4fbb
Clean up components.md
Sveb Jul 17, 2025
b06efac
Taking the block-collection component
Sveb Jul 21, 2025
d31c91f
Taking the grid-collections component as well.
Sveb Jul 21, 2025
94304d5
Update COMPONENTS.md
Sveb Jul 21, 2025
e626674
move the component styles to the theme files
Sveb Jul 23, 2025
279744a
Clean up component list
Sveb Jul 23, 2025
82e0566
add spacing
lux-v Jul 23, 2025
d24c553
add spacing
lux-v Jul 23, 2025
c69bfac
Merge branch 'UCLALibrary:main' into main
lux-v Aug 5, 2025
0f9c0aa
update component name
lux-v Aug 6, 2025
a10aa20
Update Button definition
lux-v Aug 11, 2025
7f9084e
Update COMPONENTS.md
lux-v Aug 11, 2025
4b9de5d
Update COMPONENTS.md
lux-v Aug 11, 2025
f3b329f
Remove duplicates
lux-v Aug 11, 2025
2f4300d
remove duplicates
lux-v Aug 11, 2025
2cde0d3
remove duplicates
lux-v Aug 11, 2025
df42ca4
Remove already existing components
lux-v Aug 11, 2025
3db154c
Merge branch 'main' into main
lux-v Aug 12, 2025
9287f6d
take a component
lux-v Aug 12, 2025
33787b8
update package
Sveb Aug 14, 2025
fe7041b
add a component
lux-v Aug 15, 2025
05911af
Take a component
Sveb Aug 15, 2025
92f95f4
adjust prop for block anchor nav
lux-v Aug 15, 2025
b876c86
take a component
lux-v Aug 15, 2025
1d0497d
Update COMPONENTS.md
lux-v Aug 18, 2025
2e670a6
Merge remote-tracking branch 'upstream/main'
Sveb Aug 18, 2025
eec9a91
Merge branch 'main' into main
lux-v Aug 18, 2025
09043d2
Merge remote-tracking branch 'upstream/main'
Sveb Aug 18, 2025
4a3040f
Taking the DropdownSingleSelect
Sveb Aug 19, 2025
99240ef
Merge remote-tracking branch 'upstream/main'
Sveb Aug 20, 2025
f72144c
Take the ButtonDropdownSearch component
Sveb Aug 20, 2025
8301316
Merge remote-tracking branch 'upstream/main'
Sveb Aug 22, 2025
3b3b82a
update PR with new spec.js files, uses the font mixins, adds the dlc …
Sveb Aug 22, 2025
69b3c6e
runs eslin:fix
Sveb Aug 22, 2025
9beaa8f
Merge branch 'UCLALibrary:main' into main
lux-v Aug 26, 2025
b1385a3
Adds the default theme to the styles
Sveb Aug 27, 2025
99d8a56
Update ExcerptPod.spec.js
Sveb Aug 27, 2025
b87f27e
Merge remote-tracking branch 'upstream/main'
Sveb Aug 27, 2025
95d50e6
adding the correct packageMenager version for netlify to see.
Sveb Aug 27, 2025
3aeb5a6
Merge pull request #30 from Sveb/installing-the-correct-pnpnm
Sveb Aug 27, 2025
16e863a
Merge remote-tracking branch 'upstream/main'
Sveb Aug 27, 2025
b40378b
Merge branch 'main' into NotesAccordion
Sveb Aug 27, 2025
9943c53
Update ExcerptPod.vue
Sveb Aug 27, 2025
8dbaec4
Adjust the position of the caret-icon when the accordion is opned.
Sveb Sep 2, 2025
3676437
removes the packageManager note for netlify
Sveb Sep 2, 2025
dfc38ff
remove redundant files
Sveb Sep 2, 2025
73a286e
Merge branch 'UCLALibrary:main' into main
lux-v Sep 2, 2025
64208d8
Merge remote-tracking branch 'upstream/main'
Sveb Sep 2, 2025
e461358
Merge branch 'main' into NotesAccordion
Sveb Sep 2, 2025
d677934
Merge branch 'main' into NotesAccordion
Sveb Sep 8, 2025
651c182
Merge branch 'main' into NotesAccordion
lux-v Oct 20, 2025
499326c
Merge branch 'main' into NotesAccordion
pghorpade Oct 20, 2025
028d02e
Merge branch 'main' into NotesAccordion
Sveb Oct 24, 2025
2d5206e
Add realistic text content
Sveb Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/vue-component-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@
"engines": {
"pnpm": "^9.12.1"
}
}
}
64 changes: 64 additions & 0 deletions packages/vue-component-library/src/lib-components/ExcerptPod.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script setup lang="ts">
// Imports
import { computed, defineProps } from 'vue'
import NotesAccordion from '@/lib-components/NotesAccordion.vue'
import { useTheme } from '@/composables/useTheme'

const props = withDefaults(defineProps<ExcerptPodProps>(), {
title: '',
subtitle: '',
text: '',
accordions: () => [],
labelOpen: '',
labelClose: '',
})

const theme = useTheme()

// Props
interface ExcerptPodProps {
title: string
subtitle: string
text: string
accordions: Array<{
title: string
text: string
}>
labelOpen: string
labelClose: string
}

// Computed
const classes = computed(() => ['excerpt-pod', theme?.value || ''])

const showAccordion = computed(() => {
return (
props.accordions.length > 0
&& props.accordions.some(accordion => accordion.title || accordion.text)
)
})
</script>

<template>
<div :class="classes">
<!-- Title -->
<h5 class="title" v-html="title" />
<!-- Info -->
<div class="info">
<h6 class="subtitle" v-html="subtitle" />
<div class="text-excerpt">
<div class="text" v-html="text" />
<NotesAccordion
v-if="showAccordion"
:items="accordions"
:label-open="labelOpen"
:label-close="labelClose"
/>
</div>
</div>
</div>
</template>

<style lang="scss" scoped>
@import "@/styles/dlc/_excerpt-pod.scss";
</style>
115 changes: 115 additions & 0 deletions packages/vue-component-library/src/lib-components/NotesAccordion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<script setup lang="ts">
// Imports
import {
computed,
defineProps,
nextTick,
onMounted,
onUnmounted,
ref,
} from 'vue'
import SvgArrowDown from 'ucla-library-design-tokens/assets/svgs/icon-caret-down.svg'
import type { ComponentPublicInstance } from 'vue'
import { useTheme } from '@/composables/useTheme'

const props = withDefaults(defineProps<NotesAccordionItem>(), {
items: () => [],
labelOpen: 'Less',
labelClose: 'More',
})

const theme = useTheme()

// Props
interface NotesAccordionItem {
items: Array<{
title: string
text: string
}>
labelOpen?: string
labelClose?: string
}
// Data
const isOpen = ref(false)
const textRefs = ref<(HTMLElement | null)[]>([])
const textHeight = ref(0)

// Computed
const classes = computed(() => [
'notes-accordion',
theme?.value || '',
{ 'is-open': isOpen.value },
])

const dynamicLabel = computed(() =>
isOpen.value ? props.labelOpen : props.labelClose
)

const wrapperStyles = computed(() => ({
height: isOpen.value ? `${textHeight.value}px` : '0',
}))

// Methods
function measureTextHeight() {
let totalHeight = 0
for (const ref of textRefs.value) {
if (ref)
totalHeight += ref.getBoundingClientRect().height
}

textHeight.value = totalHeight
}

function toggle() {
isOpen.value = !isOpen.value
nextTick(() => {
measureTextHeight()
})
}

function getTextRef(idx: number) {
return (el: Element | ComponentPublicInstance | null) => setTextRef(idx, el)
}

function setTextRef(idx: number, el: Element | ComponentPublicInstance | null) {
// If it's a Vue component instance, get its $el property
const element
= el && '$el' in el ? (el.$el as HTMLElement) : (el as HTMLElement | null)
textRefs.value[idx] = element
}

// Lifecycle Hook
onMounted(() => {
measureTextHeight()
window.addEventListener('resize', measureTextHeight)
})
onUnmounted(() => {
window.removeEventListener('resize', measureTextHeight)
})
</script>

<template>
<div :class="classes">
<div class="wrapper" :style="wrapperStyles">
<div
v-for="(item, idx) in items"
:key="idx"
:ref="getTextRef(idx)"
class="text-wrapper"
>
<span class="title" v-html="item.title" />
<div class="text" v-html="item.text" />
</div>
</div>
<button class="btn" :aria-expanded="isOpen" @click="toggle">
<transition name="fade-label" mode="out-in">
<span :key="dynamicLabel" class="label" v-html="dynamicLabel" />
</transition>
<SvgArrowDown class="caret-icon" />
</button>
</div>
</template>

<style lang="scss" scoped>
@import "@/styles/dlc/_notes-accordion.scss";
</style>
20 changes: 20 additions & 0 deletions packages/vue-component-library/src/stories/ExcerptPod.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
describe('Funkhaus / ExcerptPod', () => {
it('Default', () => {
cy.visit(
'/iframe.html?id=funkhaus-excerptpod--default&args=&viewMode=story'
)
cy.get('.excerpt-pod').should('exist')
cy.get('.excerpt-pod .title').should('exist')
cy.get('.excerpt-pod .subtitle').should('exist')
cy.get('.excerpt-pod .text').should('exist')
cy.percySnapshot('Funkhaus / ExcerptPod: Default')
})

it('Renders NotesAccordion when accordions are present', () => {
cy.visit(
'/iframe.html?id=funkhaus-excerptpod--more-sections&args=&viewMode=story'
)
cy.get('.excerpt-pod .notes-accordion').should('exist')
cy.get('.notes-accordion .btn').should('exist')
})
})
88 changes: 88 additions & 0 deletions packages/vue-component-library/src/stories/ExcerptPod.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { computed } from 'vue'
import ExcerptPod from '@/lib-components/ExcerptPod.vue'

export default {
title: 'Funkhaus / ExcerptPod',
component: ExcerptPod,
argTypes: {
title: {
control: 'text',
description: 'Accordion title (HTML allowed)',
},
text: {
control: 'text',
description: 'Accordion content (HTML allowed)',
},
accordions: {
control: 'object',
description: 'Array of accordion sections',
},
labelOpen: { control: 'text', description: 'Label when open' },
labelClose: { control: 'text', description: 'Label when closed' },
},
}

function Template(args) {
return {
components: { ExcerptPod },
provide() {
return {
theme: computed(() => 'dlc'),
}
},
setup() {
return { args }
},
template: `
<ExcerptPod
:title="args.title"
:text="args.text"
:subtitle="args.subtitle"
:accordions="args.accordions"
:labelOpen="args.labelOpen"
:labelClose="args.labelClose"
/>
`,
}
}

export const Default = Template.bind({})
Default.args = {
title: 'Notes',
subtitle: 'Subtitle goes hereeee',
text: 'This digital collection is comprised of selected digitized photographic negatives from the analog photographic archive. Digitization and description of this collection is ongoing. The analog collection consists of photonegatives documenting events and people in Southern California and photographic prints documenting events and people in Southern California, the U.S., and the world. The material originates from the Los Angeles Times newspaper and includes glass negatives (ca. 1918-1932), nitrate negatives (ca. 1925-45), and safety negatives (ca. 1935-present). Also includes prints and negatives from the Los Angeles Times Orange County and San Diego bureaus.',
accordions: [
{
title: 'Accordion Section',
text: 'Accordion content goes here. It can be as long as you want, and it can include <b>HTML</b> tags.',
},
],
labelOpen: 'Show Less',
labelClose: 'Show More',
}
export const EmptyProps = Template.bind({})
EmptyProps.args = {
...Default.args,
accordions: [{}],
}

export const MoreSections = Template.bind({})
MoreSections.args = {
...Default.args,
accordions: [
{
title: 'Section 1',
text: 'First section content.',
},
{
title: 'Section 2',
text: 'Second section content.',
},
{
title: 'Section 3',
text: 'Third section content.',
},
],
labelOpen: 'Collapse All',
labelClose: 'Expand All',
}
20 changes: 20 additions & 0 deletions packages/vue-component-library/src/stories/NotesAccordion.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
describe('Funkhaus / NotesAccordion', () => {
it('Default', () => {
cy.visit(
'/iframe.html?id=funkhaus-notesaccordion--default&args=&viewMode=story'
)
cy.get('.notes-accordion').should('exist')
cy.get('.notes-accordion .btn').should('exist')
cy.get('.notes-accordion .label').should('exist')
cy.percySnapshot('Funkhaus / NotesAccordion: Default')
})

it('Toggles open/close label on button click', () => {
cy.visit(
'/iframe.html?id=funkhaus-notesaccordion--default&args=&viewMode=story'
)
cy.get('.notes-accordion .btn').click()
cy.get('.notes-accordion').should('have.class', 'is-open')
cy.get('.notes-accordion .label').should('exist')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { computed } from 'vue'
import NotesAccordion from '@/lib-components/NotesAccordion.vue'

export default {
title: 'Funkhaus / NotesAccordion',
component: NotesAccordion,
argTypes: {
items: {
control: 'object',
description: 'Array of accordion sections',
},
labelOpen: { control: 'text', description: 'Label when open' },
labelClose: { control: 'text', description: 'Label when closed' },
},
}

function Template(args) {
return {
components: { NotesAccordion },
provide() {
return {
theme: computed(() => 'dlc'),
}
},
setup() {
return { args }
},
template: `
<NotesAccordion
:items="args.items"
:labelOpen="args.labelOpen"
:labelClose="args.labelClose"
/>
`,
}
}

export const Default = Template.bind({})
Default.args = {
items: [
{
title: 'Background',
text: 'IInani oratio numquam ea ius, per nihil mollis percipitur te. Mundi omittam fastidii ius ex. Mel ex everti consequat, sit equidem corrumpit adversarium cu. Sed an facer utroque. Pro dictas praesent delicatissimi in, ceteros nostrum blandit cu nec. Audire iisque id vis, sea cu omnes democritum temporibus.Eu vel dicam soluta, id omnis impetus pro. Error vocibus tacimates vim ut. Est in eirmod oblique.Inani oratio numquam ea ius, per nihil mollis percipitur te. Mundi omittam fastidii ius ex. Mel ex everti consequat, sit equidem corrumpit adversarium cu. Sed an facer utroque. Pro dictas praesent delicatissimi in, ceteros nostrum blandit cu nec. Audire iisque id vis, sea cu omnes democritum temporibus.Eu vel dicam soluta, id omnis impetus pro. Error vocibus tacimates vim ut. Est in eirmod oblique.',
},
],
}

export const MoreSections = Template.bind({})
MoreSections.args = {
items: [
{
title: 'Section 1',
text: 'First section content.',
},
{
title: 'Section 2',
text: 'Second section content.',
},
{
title: 'Section 3',
text: 'Third section content.',
},
],
labelOpen: 'Collapse All',
labelClose: 'Expand All',
}
Loading