Skip to content

Commit

Permalink
feat: use shared highlight component in vue3 (#6051)
Browse files Browse the repository at this point in the history
* wip: use shared highlight component in vue3

* fragment as nonHighlightedTagName

* chore: update deps

* docs: rename Vue 3 example

* fix build and tests

* revert yarn.lock

* rename highlighter

---------

Co-authored-by: Sarah Dayan <[email protected]>
  • Loading branch information
aymeric-giraudet and sarahdayan authored Feb 26, 2024
1 parent cdba2a2 commit 2974343
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 19 deletions.
6 changes: 3 additions & 3 deletions examples/vue/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"version": "0.41.0",
"private": true,
"scripts": {
"build": "NODE_OPTIONS=--openssl-legacy-provider -cli-service ssr:build",
"serve": "NODE_OPTIONS=--openssl-legacy-provider -cli-service ssr:serve",
"start": "NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider -cli-service ssr:serve --mode production"
"build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service ssr:build",
"serve": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service ssr:serve",
"start": "NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider vue-cli-service ssr:serve --mode production"
},
"dependencies": {
"algoliasearch": "4.22.1",
Expand Down
1 change: 1 addition & 0 deletions packages/vue-instantsearch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
},
"dependencies": {
"instantsearch.js": "4.65.0",
"instantsearch-ui-components": "0.3.0",
"mitt": "^2.1.0"
},
"peerDependencies": {
Expand Down
10 changes: 7 additions & 3 deletions packages/vue-instantsearch/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,13 @@ function outputs(vueVersion) {
];

const external = (id) =>
['algoliasearch-helper', 'instantsearch.js', 'vue', 'mitt'].some(
(dep) => id === dep || id.startsWith(`${dep}/`)
);
[
'algoliasearch-helper',
'instantsearch.js',
'instantsearch-ui-components',
'vue',
'mitt',
].some((dep) => id === dep || id.startsWith(`${dep}/`));

const cjs = {
input: 'src/instantsearch.js',
Expand Down
3 changes: 1 addition & 2 deletions packages/vue-instantsearch/src/components/Highlight.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

<script>
import { createSuitMixin } from '../mixins/suit';
import AisHighlighter from './Highlighter.vue';
import AisHighlighter from '../util/vue-compat/Highlighter';
export default {
name: 'AisHighlight',
Expand Down
69 changes: 69 additions & 0 deletions packages/vue-instantsearch/src/components/Highlighter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { createHighlightComponent } from 'instantsearch-ui-components';
import {
getHighlightedParts,
getPropertyByPath,
unescape,
} from 'instantsearch.js/es/lib/utils';

import { createElement, Fragment } from '../util/pragma';

const Highlight = createHighlightComponent({ createElement, Fragment });

export default {
name: 'AisHighlighter',
props: {
hit: {
type: Object,
required: true,
},
attribute: {
type: String,
required: true,
},
highlightedTagName: {
type: String,
default: 'mark',
},
suit: {
type: Function,
required: true,
},
highlightProperty: {
type: String,
required: true,
},
preTag: {
type: String,
required: true,
},
postTag: {
type: String,
required: true,
},
},
render() {
const property =
getPropertyByPath(this.hit[this.highlightProperty], this.attribute) || [];
const properties = Array.isArray(property) ? property : [property];

const parts = properties.map((singleValue) =>
getHighlightedParts(unescape(singleValue.value || '')).map(
({ value, isHighlighted }) => ({
// We have to do this because Vue gets rid of TextNodes with a single white space
value: value === ' ' ? ' ' : value,
isHighlighted,
})
)
);

return createElement(Highlight, {
classNames: {
root: this.suit(),
highlighted: this.suit('highlighted'),
},
highlightedTagName: this.highlightedTagName,
nonHighlightedTagName: Fragment,
parts,
});
},
};
3 changes: 1 addition & 2 deletions packages/vue-instantsearch/src/components/Snippet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

<script>
import { createSuitMixin } from '../mixins/suit';
import AisHighlighter from './Highlighter.vue';
import AisHighlighter from '../util/vue-compat/Highlighter';
export default {
name: 'AisSnippet',
Expand Down
22 changes: 22 additions & 0 deletions packages/vue-instantsearch/src/util/pragma.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { h, Fragment } from 'vue';

export const createElement = (tag, props, children) => {
if (!children) {
return h(tag, props);
}

if (tag === Fragment) {
return h(tag, Array.isArray(children) ? children : [children]);
}

// It does work to just pass a string but outputs a warning about performance issues
const newChildren =
typeof children === 'string' ? { default: () => children } : children;
// Passing a `children` prop to a DOM element outputs a warning
const newProps =
typeof tag === 'string' ? props : Object.assign(props, { children });

return h(tag, newProps, newChildren);
};

export { Fragment };
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@
</template>

<script>
import { parseAlgoliaHit } from '../util/parseAlgoliaHit';
import { getDefaultSlot, renderCompat, isVue3 } from '../util/vue-compat';
import { parseAlgoliaHit } from '../../parseAlgoliaHit';
const TextNode = isVue3
? (props, context) => context.slots.default()
: {
render: renderCompat(function () {
return getDefaultSlot(this);
}),
};
const TextNode = {
render() {
return this.$slots.default;
},
};
export default {
name: 'AisHighlighter',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Highlighter-vue2.vue';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../components/Highlighter';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './index-vue2';
7 changes: 7 additions & 0 deletions scripts/prepare-vue3.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ fs.writeFileSync(
),
"export * from './index-vue3';"
);
fs.writeFileSync(
path.resolve(
__dirname,
'../packages/vue-instantsearch/src/util/vue-compat/Highlighter/index.js'
),
"export { default } from './index-vue3';"
);

console.log('switching to Vue 3 for Jest');
shell.sed(
Expand Down

0 comments on commit 2974343

Please sign in to comment.